ExecutorService的submit()方法
ExecutorService总共有三个submit方法:
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);
在AbstractExecutorService中的实现如下:
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;
}
实际返回的是FutureTask对象:
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);
}
FutureTask的继承关系如下:
public class FutureTask<V> implements RunnableFuture<V> {......
}public interface RunnableFuture<V> extends Runnable, Future<V> {......
}
execute执行FutureTask的run方法时,实际执行的是Callable的call方法,并set call()方法的返回值
public void run() {......Callable<V> c = callable;......result = c.call();......set(result);......
}protected void set(V v) {......outcome = v;......
}
最终调用submit()返回的、Future的、get()方法时,实际返回的是call()方法的返回值
public V get() throws InterruptedException, ExecutionException {......return report(s);
}private V report(int s) throws ExecutionException {Object x = outcome;if (s == NORMAL)return (V)x;......
}
再回到FutureTask构造方法
- 入参为Runnable时,执行Executors.callable()包装后返回的Callable类,返回值Future.get()的结果为null
- 入参为Runnable和result时,执行Executors.callable()包装后返回的Callable类,返回值Future.get()的结果为传入的result
- 入参为Callable时,则直接执行的传入的Callable对象的call()方法,返回值Future.get()的结果为call()的返回值
public FutureTask(Runnable runnable, V result) {this.callable = Executors.callable(runnable, result);this.state = NEW; // ensure visibility of callable
}public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW; // ensure visibility of callable
}
查看Executors.callable()方法,新建内部类RunnableAdapter,call()方法在执行Runnable的run()方法之后返回传入的result
public static <T> Callable<T> callable(Runnable task, T result) {......return new RunnableAdapter<T>(task, result);
}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;}
}
综上所述:
- Future<?> submit(Runnable task);
- 执行Runnable的run()方法之后,Future.get()返回null
- <T> Future<T> submit(Runnable task, T result);
- 执行Runnable的run()方法之后,Future.get()返回传入的result
- <T> Future<T> submit(Callable<T> task);
- 执行Callable的call()方法之后,Future.get()返回call()方法返回值
补充:
调用submit(Runnable task)时,如果入参本身为FutureTask,submit()返回的Futrue.get()仍然为null,将与预期不符。
解决办法:调用线程池的execute()方法
ExecutorService pool = Executors.newCachedThreadPool();
FutureTask<Boolean> futureTask = new FutureTask<>(new Callable<Boolean>() {@Overridepublic Boolean call() throws Exception {return Boolean.FALSE;}
});
pool.execute(futureTask);
Boolean result = futureTask.get();
ExecutorService的submit()方法相关推荐
- ExecutorService中submit和execute的区别转
在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...
- ExecutorService中submit和execute的区别(转)
在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...
- 线程池中submit()方法与execute()方法的区别
execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提 ...
- 13.ThreadPoolExecutor线程池之submit方法
jdk1.7.0_79 在上一篇<ThreadPoolExecutor线程池原理及其execute方法>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法 ...
- 慎用jQuery中的submit()方法
今天在做项目的过程中用到了submit()提交表单. 折腾许久很是郁闷,经过多方资料查询和亲测后,得出结论: 一定要慎用submit()方法 首先,在form表单中一定不要将input中的name或i ...
- jquery 通过submit()方法 提交表单示例
jquery 通过submit()方法 提交表单示例: 本示例:以用户注册作为例子.使用jquery中的submit()方法实现表单提交. 注:本示例仅提供了对表单的验证,本例只用选用了三个字段作为测 ...
- js 用submit()方法提交表单,页面闪退问题以及解决方法
1.今天遇到一种情况,js使用submit方法提交表单,怎么都提交不过去,加断点倒跳过去了,主要实现的是这样的一个功能,点击一个按钮触发一个方法,在方法底下再提交表单过去,主要代码如下: <bu ...
- ExecutorService的shutdownNow方法注意事项
当通过shutdownNow来强行关闭ExecutorService时,它会尝试取消正在执行的任务并返回所有已提交但尚未开始的任务:注意:调用shutdownNow在关闭过程中只会返回尚未开始的任务, ...
- 探究ExecutorService的invokeAll()方法获取的结果是否具有顺序性
探究invokeAll()方法 个人粗糙的主页 该博客源码存放于 github 背景:在用ExecutorService做了一个多线程查询数据并导出之后,对它的invokeAll()方法产生了一个想法 ...
最新文章
- 深度学习常见问题解析
- SQLServer-sysobjects-type
- rat/rats--用有理数形式表示矩阵
- Coursera吴恩达《卷积神经网络》课程笔记(4)-- 人脸识别与神经风格迁移
- 【原创】二级指针中在内存中的样子
- 篇二:Eclipse安装配置Maven
- 手写自己的MyBatis框架-V2.0结果集处理
- Spring Cloud Sleuth + Zipkin + RabbitMQ +MySQL(三)
- markdown 本地链接_Markdown的使用
- 如何在Vue中使用Font Awesome?
- 明解c语言中级篇微盘,明解C语言:中级篇
- 描述Map/Reduce框架的清明上河图
- Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案
- MapABC Flex地图官方API应用整理
- keil中 如何解决warning L13:Recursive call to Function 及overlay解释
- 【颜纠日记】精华乳,精华液,精华水和化妆水相通吗,分享操纵手段
- UIQ全方位实现与ActiveSync进行数据交换(转)
- firefox添加百度搜索引擎
- 命名实体识别NER探索(1)
- 上海东锦江希尔顿逸林酒店圆满落幕