/ 技术向  

多线程相关知识与实现

线程、多线程、线程池

参考博客:https://www.jianshu.com/p/b8197dd2934c

线程:进程中负责程序执行的执行单元。一个进程中至少有一个线程。

多线程:解决多任务同时执行的需求,合理使用 CPU 资源。多线程的运行是根据 CPU 切换完成,如何切换由 CPU 决定,因此多线程运行具有不确定性。

线程池:基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。

线程 - 创建线程的三种方式

1.继承 Thread 类,扩展线程

  • 继承 Thread 类,重写 run() 方法。
  • 创建线程对象并用 start() 方法启动线程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class DemoThread extends Thread {

private String threadName;

public DemoThread(String name) {
// 编写子类的构造方法,可缺省
threadName = name;
}

@Override
public void run() {
// 编写自己的线程代码
System.out.println(threadName);
}
}


// 测试方法不要用 @Test 要用 main()s
public class ThreadTest() {
public static void main(String[] args) {
DemoThread t1 = new DemoThread("自定义线程 Thread");
t1.start();
}
}

/* out

自定义线程 Thread

*/

2.实现 Runnable 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class DemoRunnable implements Runnable {

private String threadName;

DemoRunnable(String name){
threadName = name;
}

@Override
public void run() {
System.out.println(threadName);
}
}

public class ThreadTest() {
public static void main(String[] args) {
Thread t2 = new Thread(new DemoRunnable("自定义线程 Runnable"));
t2.start();
}
}

/* out

自定义线程 Runnable

*/

3.通过线程池创建线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 同上实现一个 Runnable 接口
public class DemoRunnable implements Runnable {

private String threadName;

DemoRunnable(String name){
threadName = name;
}

@Override
public void run() {
System.out.println(threadName);
}
}

public class ThreadTest() {

// 线程池数量
private static int POOL_NUM = 10;

public static void main(String[] args) {
DemoThread t1 = new DemoThread("自定义线程 Thread");
t1.start();

DemoRunnable r=new DemoRunnable("自定义线程 Runnable");
Thread t2 = new Thread(r);
t2.start();

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(POOL_NUM);
for (int i=0; i<POOL_NUM; i++) {
DemoRunnable thread = new DemoRunnable("线程池线程 " + i);
// r.sleep(1000);
fixedThreadPool.execute(thread);
}
// 关闭线程池
fixedThreadPool.shutdown();
}
}

/* out

自定义线程 Runnable

*/

接下来两个问题

  1. Executors 创建 4 种预定义线程
  2. ExecutorThreadPool 如何使用

Q&A

1)线程和进程有什么区别?

一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。
而线程是在进程中执行的一个任务。

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。

不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。

别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。

2)如何在 Java 中实现线程?

创建线程有两种方式:

一、继承 Thread 类,扩展线程。

二、实现 Runnable 接口。

3)Thread 类中的 start() 和 run() 方法有什么区别?

调用 start() 方法才会启动新线程;

如果直接调用 Thread 的 run() 方法,它的行为就会和普通的方法一样;

为了在新的线程中执行我们的代码,必须使用 Thread.start() 方法。