⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 http://cmsblogs.com/?p=2444 「小明哥」欢迎转载,保留摘要,谢谢!

作为「小明哥」的忠实读者,「老艿艿」略作修改,记录在理解过程中,参考的资料。


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

1. 简介

经历了 Java 内存模型、J.U.C 基础之 AQS 、CAS 、Lock 、并发工具类、并发容器、阻塞队列、Atomic 类后,我们开始 J.U.C 的最后一部分:线程池。在这个部分你将了解到下面四个部分:

  1. 线程池的基础架构
  2. 线程池的原理分析
  3. 线程池核心类的源码分析
  4. 线程池调优

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 等类的静态工厂方法,通过这些工厂方法我们可以得到相对应的对象。

  1. 创建并返回设置有常用配置字符串的 ExecutorService 的方法。
  2. 创建并返回设置有常用配置字符串的 ScheduledExecutorService 的方法。
  3. 创建并返回“包装的” ExecutorService 方法,它通过使特定于实现的方法不可访问来禁用重新配置。
  4. 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。
  5. 创建并返回非闭包形式的 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);

Future

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 的返回值。

666. 彩蛋

如果你对 Java 并发感兴趣,欢迎加入我的知识星球一起交流。

知识星球

文章目录
  1. 1. 1. 简介
  2. 2. 2. Executor 体系
    1. 2.1. 2.1 Executor
    2. 2.2. 2.2 ExcutorService
    3. 2.3. 2.3 AbstractExecutorService
    4. 2.4. 2.4 ScheduledExecutorService
    5. 2.5. 2.5 ThreadPoolExecutor
    6. 2.6. 2.6 ScheduledThreadPoolExecutor
    7. 2.7. 2.7 Executors
  3. 3. 3. Future 体系
    1. 3.1. 3.1 Future
    2. 3.2. 3.2 RunnableFuture
    3. 3.3. 3.3 FutureTask
  4. 4. 666. 彩蛋