作为 JAVA 程序员,无论是技术面试、项目研发或者是学习框架源码,不彻底掌握 Java 多线程的知识,做不到心中有数,干啥都没底气,尤其是技术深究时往往略显发憷 。坐稳扶好,通过今天的分享,能让你轻松 get 如下几点 。
1. Executor 框架家族简介;Executor 家族简介一图胜千言,脑中有图心不慌 。
2. 源码解读:线程池状态以及状态流转;
3. 源码解读:部分成员变量及方法;
4. 源码解读:任务提交submit方法背后;
5. 源码揭秘之后的反思;
6. 寄语 。
文章插图
executor 家族简图
(一)Executor 接口 。
public interface Executor {void execute(Runnable command);}
Executor 是一个接口(主要用于定义规范),定义了 execute 方法,用于接收 Runnable 对象 。(二)ExecutorService 接口 。
public interface ExecutorService extends Executor {// ... ...<T> Future<T> submit(Callable<T> task);<T> Future<T> submit(Runnable task, T result);Future<?> submit(Runnable task);// ... ...}
ExecutorService 也是一个接口,继承了 Executor 接口,增加了更多方法,相当于扩展了 Executor 接口的功能,例如定义了 submit() 系列方法,支持任务执行后得到返回结果 。(三)AbstractExecutorService 抽象类 。
public abstract class AbstractExecutorService implements ExecutorService {// ... ...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);}public Future<?> submit(Runnable task) {if (task == null) throw new NullPointerException();RunnableFuture<Void> ftask = newTaskFor(task, null);execute(ftask);return ftask;}public <T> Future<T> submit(Runnable task, T result) {if (task == null) throw new NullPointerException();RunnableFuture<T> ftask = newTaskFor(task, result);execute(ftask);return ftask;}public <T> Future<T> submit(Callable<T> task) {if (task == null) throw new NullPointerException();RunnableFuture<T> ftask = newTaskFor(task);execute(ftask);return ftask;}// ... ...}
AbstractExecutorService 是一个抽象类,实现了 ExecutorService 接口中的部分方法,例如提供了任务提交的 submit 方法的默认实现,而 submit 方法最终会调用 execute 方法 。不过 AbstractExecutorService 并没有实现 execute 方法,相当于为子类留了个口子,让子类去灵活扩展(钩子函数) 。
(四)ScheduledExecutorService 接口 。
public interface ScheduledExecutorService extends ExecutorService {public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);}
ScheduledExecutorService 接口继承了 ExecutorService,增加定时调度的方法,使其成为一个可定时调度任务的接口,相当于扩展了 ExecutorService 的功能 。(五)ScheduledThreadPoolExecutor 类 。
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {// ... ...}
ScheduledThreadPoolExecutor 类继承自 ThreadPoolExecutor 类,并且实现了 ScheduledExecutorService 接口,变成一个可定时调度任务的线程池 。(六)ThreadPoolExecutor 类 。
public class ThreadPoolExecutor extends AbstractExecutorService {// ... ...}
ThreadPoolExecutor 继承 AbstractExecutorService 抽象类,并实现了 execute 等一系列方法 。(七)Executors 类 。
public class Executors {// ... ...public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}// ... ...}
研发人员可以通过 Executors 工厂类来创建线程池并返回一个ExecutorService 对象,而内部几乎全是对 ThreadPoolExecutor 的封装 。通过 Executor 的家族简单认识,应该能感觉到 ThreadPoolExecutor 类的重要性,所以接下来要重点对 ThreadPoolExecutor 类的源码进行剖析 。
源码解读:线程池状态以及状态流转
文章插图
推荐阅读
- AI人工智能:JAVA教你拍照识别文字 并语音播报
- JAVA程序员常用的几个工具类
- JAVA并发-AtomicInteger
- Java正则表达式详解
- 美团对 Java 新一代垃圾回收器 ZGC 的探索与实践
- java中的装箱和拆箱
- 2019年的6个JavaScript用户认证库
- 又一个小而美的Java Web框架:Solon
- 万字详文:Java内存泄漏、性能优化、宕机死锁的N种姿势
- 笔记本电池保养方法