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()方法相关推荐

  1. ExecutorService中submit和execute的区别转

    在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...

  2. ExecutorService中submit和execute的区别(转)

    在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...

  3. 线程池中submit()方法与execute()方法的区别

    execute()方法实际上是Executor中声明的方法,在ThreadPoolExecutor进行了具体的实现,这个方法是ThreadPoolExecutor的核心方法,通过这个方法可以向线程池提 ...

  4. 13.ThreadPoolExecutor线程池之submit方法

    jdk1.7.0_79  在上一篇<ThreadPoolExecutor线程池原理及其execute方法>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法 ...

  5. 慎用jQuery中的submit()方法

    今天在做项目的过程中用到了submit()提交表单. 折腾许久很是郁闷,经过多方资料查询和亲测后,得出结论: 一定要慎用submit()方法 首先,在form表单中一定不要将input中的name或i ...

  6. jquery 通过submit()方法 提交表单示例

    jquery 通过submit()方法 提交表单示例: 本示例:以用户注册作为例子.使用jquery中的submit()方法实现表单提交. 注:本示例仅提供了对表单的验证,本例只用选用了三个字段作为测 ...

  7. js 用submit()方法提交表单,页面闪退问题以及解决方法

    1.今天遇到一种情况,js使用submit方法提交表单,怎么都提交不过去,加断点倒跳过去了,主要实现的是这样的一个功能,点击一个按钮触发一个方法,在方法底下再提交表单过去,主要代码如下: <bu ...

  8. ExecutorService的shutdownNow方法注意事项

    当通过shutdownNow来强行关闭ExecutorService时,它会尝试取消正在执行的任务并返回所有已提交但尚未开始的任务:注意:调用shutdownNow在关闭过程中只会返回尚未开始的任务, ...

  9. 探究ExecutorService的invokeAll()方法获取的结果是否具有顺序性

    探究invokeAll()方法 个人粗糙的主页 该博客源码存放于 github 背景:在用ExecutorService做了一个多线程查询数据并导出之后,对它的invokeAll()方法产生了一个想法 ...

最新文章

  1. 深度学习常见问题解析
  2. SQLServer-sysobjects-type
  3. rat/rats--用有理数形式表示矩阵
  4. Coursera吴恩达《卷积神经网络》课程笔记(4)-- 人脸识别与神经风格迁移
  5. 【原创】二级指针中在内存中的样子
  6. 篇二:Eclipse安装配置Maven
  7. 手写自己的MyBatis框架-V2.0结果集处理
  8. Spring Cloud Sleuth + Zipkin + RabbitMQ +MySQL(三)
  9. markdown 本地链接_Markdown的使用
  10. 如何在Vue中使用Font Awesome?
  11. 明解c语言中级篇微盘,明解C语言:中级篇
  12. 描述Map/Reduce框架的清明上河图
  13. Q-Vision+Kvaser CAN/CAN FD/LIN总线解决方案
  14. MapABC Flex地图官方API应用整理
  15. keil中 如何解决warning L13:Recursive call to Function 及overlay解释
  16. 【颜纠日记】精华乳,精华液,精华水和化妆水相通吗,分享操纵手段
  17. UIQ全方位实现与ActiveSync进行数据交换(转)
  18. firefox添加百度搜索引擎
  19. 命名实体识别NER探索(1)
  20. 上海东锦江希尔顿逸林酒店圆满落幕

热门文章

  1. 免费发布友情链接的渠道
  2. 运用瀑布模型完成PL/SQL程序设计
  3. 互联网大脑的情绪,智商和梦境-互联网神经学系列第四篇
  4. airbnb宣布放弃使用react-native
  5. Android IPC 进程间通信
  6. “您的访问出错了”网页自动跳转贴吧404
  7. Java之父--Gosling
  8. 产品经理知识体系学习与实践指南
  9. [渝粤教育] 广东-国家-开放大学 21秋期末考试中国法律史10212k1
  10. Android:玩转ADB命令(ADB命令使用大全)