Executor接口
用于提交Runnable任务的对象,Executor接口用于将任务提交和任务运行机制
(线程的使用、调度等)分离开来,Executor接口并没有强制要求Runnable是异步执行的。
子接口
ExecutorService
扩展了Executor,提供了任务管理和获取异步结果Future新能力
ScheduledExecutorService
扩展了ExecutorService,提供了给定期限延迟执行或者定期执行的新能力
实现类
AbstractExecutorService
实现ExecutorService接口,作为默认实现类,实现了如下几个方法(这里主要描述功能,不考虑重载)
newTaskFor
将一个Runnable或一个Callable接口封装成一个RunnableFuture,从而可以获取提交的任务对应结果
submit
将任务封装为Future并提交任务
doInvokeAny/invokeAll/doInvokeAny
默认的调度机制,使用迭代器处理任务集合并收集处理结果,在超时之后会取消剩下的任务
ForkJoinPool
ForkJoinPool和其他ExecutorService不同的地方是采用了work-stealing工作窃取算法,
首先会把一个大任务分割成几个互不相关的小任务,把这些任务放在几个队列中(队列A,队列B,队列C…),
使用不同的线程处理这几个队列里的任务(线程A-队列A,线程B-队列B,线程C-队列C…),
如果有线程处理完自己的任务队列,就会从其他队列中窃取任务,ForkJoinPool采用双端队列,
从队列头获取任务处理,从其他队列尾窃取任务。
ForkJoinWorkerThread
ForkJoinPool里工作的线程,维护了自己所属的线程池和自己处理的工作队列,并没有具体逻辑实现
ForkJoinTask
ForkJoinTask是一个类线程,但是比类线程更轻,一个ForkJoinWorkerThread可以持有大量的ForkJoinTask,
ForkJoinTask是一个Future,他的高效源自于运行限制(仅能运行静态代码)。主要的两个函数
fork()用于异步执行,join()用于汇集结果,所以在使用ForkJoin框架的时候,首先要减少同步代码块的占比,
否则fork()函数效率会很低下。
需要注意的是,不要将相互依赖的任务提交到ForkJoinTask里,否则会形成有向无环图,造成两者相互等待造成死锁的情况。
任务的状态说明:
- DONE_MASK:屏蔽完成状态
- NORMAL:正常完成,完成状态
- CANCELLED:取消,完成状态
- EXCEPTIONAL:异常,完成状态
- SIGNAL:有其他任务依赖当前任务
- SMASK:状态变更时短暂持有的标记,用于CAS替换状态操作
WorkQueue
ForkJoinTask内部类,内部维护双端队列,使得ForkJoin框架的工作窃取算法能够得到对于支持,同时完成了常用的API比如剩余任务的全部撤销。
ThreadPoolExecutor
该类不展开描述,这个类是程序员最应该了解的一个类,因为在不同的需求不同的环境中,线程池的使用需求是不同的,
ThreadPoolExecutor提供了很多参数,让程序员可以更轻松的调整自己最佳的运行状态,是必须全面了解的一个类,此处无法全面展开。
ScheduledThreadPoolExecutor
提供了给定期限延迟执行或者定期执行的功能,默认情况下采用先进先出(FIFO)原则将任务放置在队列中,
如果一个任务被取消,队列里的任务不会立即被删除,如果需要立即删除则需要设置setRemoveOnCancelPolicy(boolean)为true,