【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

1.介绍

1.1 Executor框架的两级调度模型

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
应用程序通过Executor框架控制上层的调度;而下层的调度由操作系统内核控制,下层的调度不受应用程序的控制。

1.2 Executor框架的结构与成员

Executor框架主要由以下3大部分组成:
1.任务。包括被执行任务需要实现的接口:Runnable接口或Callable接口。
2.任务的执行。包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)。
3.异步计算的结果。包括接口Future和实现Future接口的FutureTask类。
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.ThreadPoolExecutor

Executor框架最核心的类是ThreadPoolExecutor,它是线程池的实现类。
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

线程池状态

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

构造方法

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

提交任务

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

关闭线程池

shutdown

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

shutdownNow

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

awaitTermination

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.1 FixedThreadPool

2.1.1 介绍

FixThreadPool被称为可重用固定线程数的线程池。

keepAliveTime为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程将被终止。
FixThreadPool把keepAliveTime设置为0L,意味着多余的空闲线程会被立即终止。

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.1.3 *队列LinkedBlockingQueue作为线程池的工作队列

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.1.4 适用场景

FixedThreadPool适用于为了满足资源管理的需求,而 需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。适用于任务量已知,相对耗时的任务。

2.2 SingleThreadPool

2.2.1 介绍

希望多个任务排队执行,任务数为1,当任务数多于1时,会放入*队列排队。任务执行完毕,这唯一的线程也不会释放。

跟自己创建单线程的区别:
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.2.2 使用

使用单个Worker线程。
SingleThreadExecutor使用*队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE)。SingleThreadExecutor使用*队列作为工作队列对线程池带来的影响与FixedThreadPool相同。
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.2.3 适用场景

SingleThreadExecutor适用于需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。

2.3 CachedThreadPool

2.3.1 介绍

CachedThreadPool是一个会根据需要创建新线程的线程池。
直白地讲,它没有容量,没有线程来取是放不进去的。它还可以无限创建。

2.3.2 构造函数

corePoolSize设置为0,maximumPoolSize设置为Integer.MAX_VALUE,keepAliveTime设置为60L(意味着CachedThreadPool中的空闲线程等待新任务的最长时间为60秒,空闲线程超过60秒后将会被终止)。

2.3.3 使用

CachedThreadPool使用没有容量的SynchronousQueue作为线程池的工作队列,
但CachedThreadPool的maximumPool是*的。这意味着,如果主线程提交任务的速度高于 maximumPool中线程处理任务的速度时,CachedThreadPool会不断创建新线程。极端情况下, CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。

【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask
SynchronousQueue是一个没有容量的阻塞队列。每个插入操作必须等待另一 个线程的对应移除操作,反之亦然。CachedThreadPool使用SynchronousQueue,把主线程提交的任务传递给空闲线程执行。
CachedThreadPool中任务传递的示意图如图所示。
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

2.3.4 适用场景

CachedThreadPool是大小*的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。

3.ScheduledThreadPoolExecutor

3.1 Timer的缺点

Timer对应的是单个后台进程,而ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。
【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask

4.FutureTask


【Java并发编程的艺术】Executor框架:ThreadPoolExecutor&ScheduledThreadPoolExecutor&FutureTask