1 什么是执行器框架(Executor FrameWork)
- 隔离任务的创建与运行的框架,使得开发任务可以专注于任务的逻辑
2 执行器框架的优势
- 通过使用执行器框架,开发者就可以专注于任务的逻辑,而不需要关心线程的创建、关闭等维护操作
- 执行器框架使用线程池中的线程来执行任务,可以避免不断的创建、销毁线程代理的性能消耗
- 同时,线程池框架提供了 Callable 接口,它可以使得任务有返回值
3 执行器框架的结构
类型 | 名称 | 描述 |
---|
接口 | Executor | 最上层的接口,定义了执行任务的方法 execute |
接口 | ExecutorService | 继承了 Executor 接口,新增了很多增强的执行任务的方法,引入了 Callable、Future 机制 |
抽象类 | AbstractExecutorService | ExecutorService 接口的默认实现类,通过引入 RunnableFuture 接口适配了 callable、runnable 接口,使得callable 接口的实现类也可以被线程池执行 |
实现类 | ThreadPoolExecutor | AbstractExecutorService 抽象类的实现类,是一个基础、标准的线程池实现 |
接口 | ScheduledExecutorService | 继承了ExecutorService 接口,增加了定时任务相关方法 |
实现类 | ScheduledThreadPoolExecutor | 继承了 ThreadPoolExecutor,实现了ScheduledExecutorService中相关定时任务方法 |
执行器工具类 | Executors | 执行器的工厂方法和实用方法,创建 ExecutorService、ScheduleExecutorService、ThreadFactory、Callable 类 |
任务结果获取类 | ExecutorCompletionService | 通过它可以使得任务的发送和获取是不同的线程,并且优先获取已经完成的任务,就不会因为等待未完成的任务而阻塞了已完成的任务 |
实现类 | ForkJoinPool | 继承了 AbstractExecutorService 抽象类,专门用于 ForkJoinTask 的线程池 |
4 AbstractExecutorService 解析
public abstract class AbstractExecutorService implements ExecutorService {
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;
}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {...}
public <T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {...}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException{...}
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit) throws InterruptedException {...}
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);
}
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,boolean timed, long nanos){...}
}
5 ThreadPoolExecutor 解析
5.1 线程池状态、线程池线程数 表示变量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
5.2 加入工作线程、工作队列、reject 的过程
- execute() 方法诠释了 加入工作线程、工作队列、reject 的逻辑
- 如果线程池中的线程数少于核心线程数,尝试开启新的线程执行该任务。返回 true 说明任务成功被执行,返回 false,则进入后面逻辑
- 如果线程数已经大于等于核心线程数,则新来的认为会直接尝试加入工作队列
- 如果任务成功加入工作队列, double-check 线程池状态,防止加入任务后状态变化。如果变化了则移除任务,并走 reject 逻辑。如果没有变,但是线程数为0,则要新建一个线程
- 如果等待队列满了,尝试开启新的线程执行,当线程数大于最大线程数时,走 reject 逻辑

public void execute(Runnable command) {
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {...}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock();
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
5.3 线程状态处理几种方法
public void shutdown() {...}
public List<Runnable> shutdownNow(){...}
public boolean isShutdown(){...}
public boolean isTerminating(){...}
public boolean isTerminated(){...}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException{..}
5.4 构造函数参数解析
变量 | 描述 |
---|
corePoolSize | 核心线程数 |
maximumPoolSize | 最大线程数 |
keepAliveTime | 线程空闲的最大时间,到了会被销毁 |
unit | keepAliveTime 对应的时间单位 |
workQueue | 工作队列的类型,即阻塞队列的类型 |
threadFactory | 线程工厂,用于创建线程 |
handler | 执行 reject 的逻辑 |
allowCoreThreadTimeOut | 使得核心线程也会过期,不在构造函数参数中! |
5.5 拒绝策略解析
- 当线程数达到最大后,如果还有任务过了,就可能会被拒绝,这是就会走拒绝逻辑
- 如果在构造函数中没有指定 拒绝策略,则会使用默认拒绝策略:AbortPolicy
- ThreadPoolExecutor 也提供了另外 3 中拒绝策略
- 同时开发者可以自定义拒绝策略
public static class AbortPolicy implements RejectedExecutionHandler {}
public static class DiscardPolicy implements RejectedExecutionHandler {}
public static class DiscardOldestPolicy implements RejectedExecutionHandler {}
public static class CallerRunsPolicy implements RejectedExecutionHandler {}
5.6 Worker 类解析
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
final Thread thread;
Worker(Runnable firstTask) {
setState(-1);
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {runWorker(this);}
}
final void runWorker(Worker w) {}
6 ScheduledThreadPoolExecutor 解析
6.1 ScheduledThreadPoolExecutor 常用方法解析
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService {
public <V> ScheduledFuture<V> schedule(callable,delay,unit) {
ScheduleFutureTask s = ScheduleFutureTask<V>(callable,triggerTime(delay,unit));
RunnableScheduledFuture<V> t = decorateTask(callable,s);
delayedExecute(t);
return t;
}
public ScheduledFuture<?> scheduleAtFixedRate(command,initialDelay,period,unit) {
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,null,triggerTime(initialDelay, unit),unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit) {
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(-delay));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
public void execute(Runnable command) {
schedule(command, 0, NANOSECONDS);
}
public Future<?> submit(Runnable task) {
return schedule(task, 0, NANOSECONDS);
}
public <T> Future<T> submit(Runnable task, T result) {
return schedule(Executors.callable(task, result), 0, NANOSECONDS);
}
public <T> Future<T> submit(Callable<T> task) {
return schedule(task, 0, NANOSECONDS);
}
}
6.2 ScheduledThreadPoolExecutor 工作原理伪源码解析
private void delayedExecute(RunnableScheduledFuture<?> task) {
if (isShutdown())
reject(task);
else {
super.getQueue().add(task);
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
else
ensurePrestart();
}
}
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}
addWorker() {
runWorker() {
getTask() {
Runnable r = timed ?workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
}
}
}
workQueue.take() {
if (delay <= 0)
return q.poll();
else
await();
}
poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0];
E x = (E) queue[s];
queue[s] = null;
if (s != 0)
siftDown(0, x);
return result;
}
7 Executors 解析
方法 | 描述 |
---|
newFixedThreadPool(nThreads, threadFactory) | 创建固定线程数的线程池(无界队列) |
newSingleThreadExecutor(threadFactory) | FixedPool nThreads 为 1的情况 |
newCachedThreadPool(threadFactory) | 当任务到时如果有线程在等待任务则直接执行,如果没有则新建一个工作线程来执行(maxPoolSize 为最大值) |
newScheduledThreadPool(corePoolSize, threadFactory) | 定时、定期任务线程池 |
defaultThreadFactory() | 返回一个默认的线程工厂 |
PrivilegedThreadFactory() | 通过 java 的 AccessController.doPrivileged 创建 run() 方法 |
callable(Runnable task, T result) | 通过 runnable 对象创建 callable 对象的方法 |
8 ExecutorCompletionService 解析
8.1 ExecutorCompletionService 核心
- 实现了 FutureTask 的子类,并重写了 done() 方法
- 当 Callable 任务完成后,会调用 set() 方法中的 done() 方法,最终将执行完的任务放入 completionQueue
private class QueueingFuture extends FutureTask<Void> {
QueueingFuture(RunnableFuture<V> task) {
super(task, null);
this.task = task;
}
protected void done() { completionQueue.add(task); }
private final Future<V> task;
}
8.2 构造函数解析
- 构造函数中必须传入一个 Executor 类,用来执行任务
- completionQueue 可以没有,默认为 LinkedBlockingQueue
public ExecutorCompletionService(Executor executor,
BlockingQueue<Future<V>> completionQueue) {
if (executor == null || completionQueue == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
this.completionQueue = completionQueue;
}
8.3 可用方法
public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
executor.execute(new QueueingFuture(f));
return f;
}
public Future<V> submit(Runnable task, V result) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task, result);
executor.execute(new QueueingFuture(f));
return f;
}
public Future<V> take() throws InterruptedException {
return completionQueue.take();
}
public Future<V> poll() {
return completionQueue.poll();
}
public Future<V> poll(long timeout, TimeUnit unit)
throws InterruptedException {
return completionQueue.poll(timeout, unit);
}
9 ForkJoinPool 解析
参考
jdk1.8u171
java 的 AccessController.doPrivileged使用