持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情
AbstractExecutorService实现原理
子类继承ExecutorService,使用模板方法,通过抽象类来实现部分公用算法,这样子类实现线程池就容易些。
抽象执行器服务部分源码如下:
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;
}
/**
执行传入的任务,只要任何一个任务被执行完成就返回,然后取消其他任务,any指任何一个tasks中的任务执行完成,timed和nacos用来表明执行超时时间
**/
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
//任务判空
if (tasks == null)
throw new NullPointerException();
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
//创建用于保存执行stub的future对象的集合
ArrayList<Future<T>> futures = new ArrayList<Future<T>>(ntasks);
//创建ExecutorCompletionService用于执行任务
ExecutorCompletionService<T> ecs =
new ExecutorCompletionService<T>(this);
try {
// 记录异常,这样如果不能获取任何result,可以抛出最后一个异常。
ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
//获取集合的迭代器
Iterator<? extends Callable<T>> it = tasks.iterator();
// 先开始一项任务,其余的增量执行
futures.add(ecs.submit(it.next()));
//任务数减1
--ntasks;
//正在执行的任务为1
int active = 1;
}
解析方法如下:
newTaskFor(Runnable runnable, T value)方法:将Runnable对象封装为FutureTask。
newTaskFor(Callable callable)方法:将Callable对象封装为FutureTask。
submit(Runnable task)方法:封装Runnable task,然后调用execute执行。
submit(Runnable task, T result)方法:封装Runnable task,然后调用execute执行,注意点还封装了结果。
submit(Callable task)方法:封装Callable task,然后调用execute执行。