0%

Java多线程实现方式

前言:复习总结一下java实现线程的三种方式与JUC中现成的4种线程池

实现线程的三种简单方式

继承java.lang.Thread类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyThread extends Thread {
public void run() {
System.out.println(getName() + "的run()方法在运行");
}
}

public class Main {
public static void main(String[] args) {
final int N = 10;
MyThread[] myThread = new MyThread[N];
for (int i = 0; i < N; i++) {
myThread[i] = new MyThread();
}
for (int i = 0; i < N; i++) {
myThread[i].start();
}
}
}
实现java.lang.Runnable接口

java只支持单继承,所以继承java.lang.Thread类有局限性,因此实现java.lang.Runnable接口是一个更好的选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyThread implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + "的run()方法在运行");
}
}

public class Main {
public static void main(String[] args) {
final int N = 10;
Thread[] threads = new Thread[N];
for (int i = 0; i < N; i++) {
threads[i] = new Thread(new MyThread());
}
for (int i = 0; i < N; i++) {
threads[i].start();
}
}
}

也可以创建一个 实现Runnable接口类的实例,赋值给多个Thread

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyThread implements Runnable {
private int num = 0;

@Override
public void run() {
for (int i = 0; i < 1000; i++) {
num++;
}
System.out.println(Thread.currentThread().getName() + " " + num);
}

public static void main(String[] args) {
MyThread myThread = new MyThread();
for (int i = 0; i < 10; i++) {
new Thread(myThread).start();
}
}
}

运行结果:

image-20200107225319309

通过Callable和FutureTask创建线程

Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式: 实现 Callable 接口。

Callable 接口类似于 Runnable,但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而 Callable 依赖 FutureTask 类获取返回结果。

Callable类图

image-20200107225335183

FutureTask类图

image-20200107225343936

代码

1
2
3
4
5
6
7
8
9
10
11
public class MyThread implements Callable<String> {

public void run() {
System.out.println("线程 " + this.toString() + "执行结束");
}

@Override
public String call() throws Exception {
return null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
try {
FutureTask<String> futureTask = new FutureTask<String>(new MyThread());
new Thread(futureTask).start();
// 获取运算结果是同步过程,即 call 方法执行完成,才能获取结果 System.out.println(futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}

}
}

image-20200107225401443

通过线程池创建线程

java.util.concurrent包中已经提供为大多数使用场景的内置线程池

image-20200107225413056

  1. Executors.newSingleThreadExecutor() 单条线程
  2. Executors.newFixedThreadPool(int n) 固定数目线程的线程池
  3. Executors.newCachedThreadPool() 创建一个可缓存的线程池,调用execute将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有60秒钟未被使用的线程。
  4. Executors.newScheduledThreadPool(int n) 支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

类图

image-20200107225448668

image-20200107225440840

Executors.newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

newSingleThreadExecutor 方法源码

核心线程数1,线程池最大数量1,线程空闲存活时间为0,时间单位毫秒,阻塞队列为LinkedBlockingQueue,允许请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM,第二个方法允许自定义ThreadFactory线程工厂

1
2
3
4
5
6
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

newSingleThreadExecutor实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
/**
* Java8 lambda
*/
// executorService.execute(() -> System.out.println(Thread.currentThread().getName()));

// 关闭线程池
executorService.shutdown();
}
}

image-20200107225638238

Executors.newFixedThreadPool

newFixedThreadPool方法源码

核心线程数n,线程池最大数量n,线程空闲存活时间为0,时间单位毫秒,阻塞队列为LinkedBlockingQueue,允许请求队列长度为Integer.MAX_VALUE,可能会堆积大量请求,导致OOM,第二个方法允许自定义ThreadFactory线程工厂

1
2
3
4
5
6
7
8
9
10
11
12
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}

newFixedThreadPool实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
public static void main(String[] args) {
final int THREADNUM = 5;
ExecutorService executorService = Executors.newFixedThreadPool(THREADNUM);
for (int i = 0; i < THREADNUM; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
// 关闭线程池
executorService.shutdown();
}
}

image-20200107225652834

Executors.newCachedThreadPool

newCachedThreadPool方法源码

核心线程数0,线程池最大数量Integer.MAX_VALUE,允许创建线程为Integer.MAX_VALUE,可能会创建大量线程,导致OOM,线程空闲存活时间为60,时间单位秒,阻塞队列为SynchronousQueue,,第二个方法允许自定义ThreadFactory线程工厂

1
2
3
4
5
6
7
8
9
10
11
12
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}

newCachedThreadPool实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
public static void main(String[] args) {
final int THREADNUM = 5;
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < THREADNUM; i++) {
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
// 关闭线程池
executorService.shutdown();
}
}

image-20200107225710890

Executors.newScheduledThreadPool

newScheduledThreadPool方法源码

核心线程数为N,线程池最大数量Integer.MAX_VALUE,允许创建线程为Integer.MAX_VALUE,可能会创建大量线程,导致OOM,线程空闲存活时间为0,时间单位毫秒,阻塞队列为BlockingQueue,允许自定义ThreadFactory线程工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

newScheduledThreadPool实例
定时执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
public static void main(String[] args) {
final int THREADNUM = 5;
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(THREADNUM);
for (int i = 0; i < THREADNUM; i++) {
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}, 1, TimeUnit.SECONDS);
}
// 关闭线程池
scheduledThreadPool.shutdown();
}
}
-------------本文结束感谢您的阅读-------------