java并发包简述之Executor

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里,否则会形成有向无环图,造成两者相互等待造成死锁的情况。

任务的状态说明:

  1. DONE_MASK:屏蔽完成状态
  2. NORMAL:正常完成,完成状态
  3. CANCELLED:取消,完成状态
  4. EXCEPTIONAL:异常,完成状态
  5. SIGNAL:有其他任务依赖当前任务
  6. SMASK:状态变更时短暂持有的标记,用于CAS替换状态操作
WorkQueue

ForkJoinTask内部类,内部维护双端队列,使得ForkJoin框架的工作窃取算法能够得到对于支持,同时完成了常用的API比如剩余任务的全部撤销。

ThreadPoolExecutor

该类不展开描述,这个类是程序员最应该了解的一个类,因为在不同的需求不同的环境中,线程池的使用需求是不同的,
ThreadPoolExecutor提供了很多参数,让程序员可以更轻松的调整自己最佳的运行状态,是必须全面了解的一个类,此处无法全面展开。

ScheduledThreadPoolExecutor

提供了给定期限延迟执行或者定期执行的功能,默认情况下采用先进先出(FIFO)原则将任务放置在队列中,
如果一个任务被取消,队列里的任务不会立即被删除,如果需要立即删除则需要设置setRemoveOnCancelPolicy(boolean)为true,