http://www.iocoder.cn/JUC/sike/ThreadPool-core/
1. 简介
经历了 Java 内存模型、J.U.C 基础之 AQS 、CAS 、Lock 、并发工具类、并发容器、阻塞队列、Atomic 类后,我们开始 J.U.C 的最后一部分:线程池。在这个部分你将了解到下面四个部分:
- 线程池的基础架构
- 线程池的原理分析
- 线程池核心类的源码分析
- 线程池调优
2. Executor 体系
我们先看线程池的基础架构图:

2.1 Executor
java.util.concurrent.Executor ,任务的执行者接口,线程池框架中几乎所有类都直接或者间接实现 Executor 接口,它是线程池框架的基础。
Executor 提供了一种将“任务提交”与“任务执行”分离开来的机制,它仅提供了一个 #execute(Runnable command) 方法,用来执行已经提交的 Runnable 任务。代码如下:
public interface Executor {
void execute(Runnable command);
}
|
2.2 ExcutorService
java.util.concurrent.ExcutorService ,继承 Executor 接口,它是“执行者服务”接口,它是为”执行者接口 Executor “服务而存在的。准确的地说,ExecutorService 提供了”将任务提交给执行者的接口( submit 方法)”,”让执行者执行任务( invokeAll , invokeAny 方法)”的接口等等。代码如下:
public interface ExecutorService extends Executor {
/**
* 启动一次顺序关闭,执行以前提交的任务,但不接受新任务
*/
void shutdown();
/**
* 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表
*/
List<Runnable> shutdownNow();
/**
* 如果此执行程序已关闭,则返回 true。
*/
boolean isShutdown();
/**
* 如果关闭后所有任务都已完成,则返回 true
*/
boolean isTerminated();
/**
* 请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
// ========== 提交任务 ==========
/**
* 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future
*/
Future<?> submit(Runnable task);
/**
* 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
/**
* 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
|
2.3 AbstractExecutorService
java.util.concurrent.AbstractExecutorService ,抽象类,实现 ExecutorService 接口,为其提供默认实现。
AbstractExecutorService 除了实现 ExecutorService 接口外,还提供了 #newTaskFor(...) 方法,返回一个 RunnableFuture 对象,在运行的时候,它将调用底层可调用任务,作为 Future 任务,它将生成可调用的结果作为其结果,并为底层任务提供取消操作。
2.4 ScheduledExecutorService
java.util.concurrent.ScheduledExecutorService ,继承 ExecutorService ,为一个“延迟”和“定期执行”的 ExecutorService 。他提供了如下几个方法,安排任务在给定的延时执行或者周期性执行。代码如下:
// 创建并执行在给定延迟后启用的 ScheduledFuture。 <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) // 创建并执行在给定延迟后启用的一次性操作。 ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) // 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期; //也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。 ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) // 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。 ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) |
2.5 ThreadPoolExecutor
大名鼎鼎的“线程池”,后续做详细介绍。
2.6 ScheduledThreadPoolExecutor
java.util.concurrent.ScheduledThreadPoolExecutor ,继承 ThreadPoolExecutor ,并且实现 ScheduledExecutorService 接口,是两者的集大成者,相当于提供了“延迟”和“周期执行”功能的 ThreadPoolExecutor 。
2.7 Executors
静态工厂类,提供了 Executor、ExecutorService 、ScheduledExecutorService、ThreadFactory 、Callable 等类的静态工厂方法,通过这些工厂方法我们可以得到相对应的对象。
- 创建并返回设置有常用配置字符串的 ExecutorService 的方法。
- 创建并返回设置有常用配置字符串的 ScheduledExecutorService 的方法。
- 创建并返回“包装的” ExecutorService 方法,它通过使特定于实现的方法不可访问来禁用重新配置。
- 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
- 创建并返回非闭包形式的 Callable 的方法,这样可将其用于需要 Callable 的执行方法中。
3. Future 体系
Future 接口和实现 Future 接口的 FutureTask 代表了线程池的异步计算结果。
AbstractExecutorService 提供了 #newTaskFor(...) 方法,返回一个RunnableFuture 对象。除此之外,当我们把一个 Runnable 或者 Callable 提交给( submit 方法)ThreadPoolExecutor 或者 ScheduledThreadPoolExecutor 时,他们则会向我们返回一个FutureTask对象。如下:
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<> submit(Runnable task);
|

3.1 Future
java.util.concurrent.Future ,作为异步计算的顶层接口,Future 对具体的 Runnable 或者 Callable 任务提供了三种操作:
- 执行任务的取消
- 查询任务是否完成
- 获取任务的执行结果
其接口定义如下:
public interface Future<V> {
/**
* 试图取消对此任务的执行
* 如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。
* 当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。
* 如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 如果在任务正常完成前将其取消,则返回 true
*/
boolean isCancelled();
/**
* 如果任务已完成,则返回 true
*/
boolean isDone();
/**
* 如有必要,等待计算完成,然后获取其结果
*/
V get() throws InterruptedException, ExecutionException;
/**
* 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
|
3.2 RunnableFuture
java.util.concurrent.RunnableFuture ,继承 Future、Runnable 两个接口,为两者的合体,即所谓的 Runnable 的 Future 。提供了一个 #run() 方法,可以完成 Future 并允许访问其结果。
public interface RunnableFuture<V> extends Runnable, Future<V> {
//在未被取消的情况下,将此 Future 设置为计算的结果
void run();
}
|
3.3 FutureTask
java.util.concurrent.FutureTask ,实现 RunnableFuture 接口,既可以作为 Runnable 被执行,也可以作为 Future 得到 Callable 的返回值。

本文深入探讨Java线程池的架构与原理,包括Executor体系、Future体系的关键概念,如ExecutorService、ScheduledExecutorService及ThreadPoolExecutor等核心类的职责与使用方法。
289

被折叠的 条评论
为什么被折叠?



