本文主要是记录一下自己看了ThreadPoolExecutor的源码后的一个大体理解,方便以后的复习,文中如果有什么错误的地方还请各位大佬们指出,万分感谢!!!
本文主要描述一下ThreadPoolExecutor中submit()与Executor()方法区别,想了解ThreadPoolExecutor的整体的逻辑看一下我的另一篇文档ThreadPoolExecutoru源码分析。
首先,Executor()方法是在Executor接口中定定义的,submit()方法定义在ExecutorService接口中,而ExecutorService接口继承了Executor接口;
1、AbstractExecutorService通过实现ExecutorService接口实现了它的三个submit方法,每个submit方法中调用了newTaskFor方法,第一、二个newTaskFor方法传了两个参数(task:任务,result:返回值),第三个newTaskFor方法传了一个Callable对象。然后将返回的RunnableFuture对象传给execute执行,话说回来submit最终还是通过executor来执行的。下面我们跟一下submit方法中newTaskFor方法做了哪些事
public Future<?> submit(Runnable task) { if (task == null) throw new NullPointerException(); RunnableFuture<Void> ftask = newTaskFor(task, null); execute(ftask); return ftask; } /** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ 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; } /** * @throws RejectedExecutionException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public <T> Future<T> submit(Callable<T> task) { if (task == null) throw new NullPointerException(); RunnableFuture<T> ftask = newTaskFor(task); execute(ftask); return ftask; }
2、 先看AbstractExecutorService中实现的传两个参数的newTaskFor方法,方法中返回一个FutureTask对象,到这里就明白了原来,submit是通过FutureTask对象来实现返回值的
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value); }
3、创建FutureTask对象时,初始化了FutureTask对象的callable参数,不难看出callable 是通过Executors类的callable方法返回的,继续追踪Executors.callable(runnable, result);
public FutureTask(Runnable runnable, V result) { this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable }
4、Executors类中的静态方法callable中返回了一个RunnableAdapter对象
public static <T> Callable<T> callable(Runnable task, T result) { if (task == null) throw new NullPointerException(); return new RunnableAdapter<T>(task, result); }
5、Executors类中有一个静态内部类RunnableAdapter实现了Callable接口,到这里就明白了,submit方法中的newTaskFor就是返回了一个传入了Callable对象的FutureTask对象
static final class RunnableAdapter<T> implements Callable<T> { final Runnable task; final T result; RunnableAdapter(Runnable task, T result) { this.task = task; this.result = result; } public T call() { task.run(); return result; } }
6、因此1中传入了Callable对象的newTaskFor(task)方法也好理解了
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { return new FutureTask<T>(callable); }
通过submit方法创建线程执行任务的流程如下:
submit()、execute()、addWorker()、new Worker()中的thread.start()、Worker中的run()、runWorker()、FutureTask中的run()、Callable中的call()、call()方法中执行的是传进来的Runnable对象中的run()