三个区别:

1、接收的参数不一样

2、submit有返回值,而execute没有

Method submit extends base method Executor.execute by creating and
returning a Future that can be used to cancel execution and/or wait for
completion.

用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,如果是失败,原因是什么。然后我就可以把所有失败的原因综合起来发给调用者。

个人觉得cancel execution这个用处不大,很少有需要去取消执行的。

而最大的用处应该是第二点。

3、submit方便Exception处理

There is a difference when looking at exception handling. If your tasks throws an exception and if it was submitted with execute this

exception will go to the uncaught exception handler (when you don't
have provided one explicitly, the default one will just print the stack
trace to System.err).
If you submitted the task with submit any thrown
exception, checked or not, is then part of the task's return status. For a task that was submitted with submit and
that terminates with an exception, the Future.get will
rethrow this exception, wrapped in an ExecutionException.

意思就是如果你在你的task里会抛出checked或者unchecked exception,而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。

比如说,我有很多更新各种数据的task,我希望如果其中一个task失败,其它的task就不需要执行了。那我就需要catch Future.get抛出的异常,然后终止其它task的执行,代码如下:

51cto上有一篇非常好的文章“Java5并发学习”(http://lavasoft.blog.51cto.com/62575/115112),下面的代码是基于它之上修改的。

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Random;
  4. import java.util.concurrent.Callable;
  5. import java.util.concurrent.ExecutionException;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8. import java.util.concurrent.Future;
  9. public class ExecutorServiceTest {
  10. public static void main(String[] args) {
  11. ExecutorService executorService = Executors.newCachedThreadPool();
  12. List<Future<String>> resultList = new ArrayList<Future<String>>();
  13. // 创建10个任务并执行
  14. for (int i = 0; i < 10; i++) {
  15. // 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
  16. Future<String> future = executorService.submit(new TaskWithResult(i));
  17. // 将任务执行结果存储到List中
  18. resultList.add(future);
  19. }
  20. executorService.shutdown();
  21. // 遍历任务的结果
  22. for (Future<String> fs : resultList) {
  23. try {
  24. System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
  25. } catch (InterruptedException e) {
  26. e.printStackTrace();
  27. } catch (ExecutionException e) {
  28. executorService.shutdownNow();
  29. e.printStackTrace();
  30. return;
  31. }
  32. }
  33. }
  34. }
  35. class TaskWithResult implements Callable<String> {
  36. private int id;
  37. public TaskWithResult(int id) {
  38. this.id = id;
  39. }
  40. /**
  41. * 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
  42. *
  43. * @return
  44. * @throws Exception
  45. */
  46. public String call() throws Exception {
  47. System.out.println("call()方法被自动调用,干活!!!             " + Thread.currentThread().getName());
  48. if (new Random().nextBoolean())
  49. throw new TaskException("Meet error in task." + Thread.currentThread().getName());
  50. // 一个模拟耗时的操作
  51. for (int i = 999999999; i > 0; i--)
  52. ;
  53. return "call()方法被自动调用,任务的结果是:" + id + "    " + Thread.currentThread().getName();
  54. }
  55. }
  56. class TaskException extends Exception {
  57. public TaskException(String message) {
  58. super(message);
  59. }
  60. }

执行的结果类似于:

  1. call()方法被自动调用,干活!!!             pool-1-thread-1
  2. call()方法被自动调用,干活!!!             pool-1-thread-2
  3. call()方法被自动调用,干活!!!             pool-1-thread-3
  4. call()方法被自动调用,干活!!!             pool-1-thread-5
  5. call()方法被自动调用,干活!!!             pool-1-thread-7
  6. call()方法被自动调用,干活!!!             pool-1-thread-4
  7. call()方法被自动调用,干活!!!             pool-1-thread-6
  8. call()方法被自动调用,干活!!!             pool-1-thread-7
  9. call()方法被自动调用,干活!!!             pool-1-thread-5
  10. call()方法被自动调用,干活!!!             pool-1-thread-8
  11. call()方法被自动调用,任务的结果是:0    pool-1-thread-1
  12. call()方法被自动调用,任务的结果是:1    pool-1-thread-2
  13. java.util.concurrent.ExecutionException: com.cicc.pts.TaskException: Meet error in task.pool-1-thread-3
  14. at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
  15. at java.util.concurrent.FutureTask.get(FutureTask.java:83)
  16. at com.cicc.pts.ExecutorServiceTest.main(ExecutorServiceTest.java:29)
  17. Caused by: com.cicc.pts.TaskException: Meet error in task.pool-1-thread-3
  18. at com.cicc.pts.TaskWithResult.call(ExecutorServiceTest.java:57)
  19. at com.cicc.pts.TaskWithResult.call(ExecutorServiceTest.java:1)
  20. at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
  21. at java.util.concurrent.FutureTask.run(FutureTask.java:138)
  22. at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
  23. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
  24. at java.lang.Thread.run(Thread.java:619)

可以看见一旦某个task出错,其它的task就停止执行。

来自:http://blog.csdn.net/peachpi/article/details/6771946

ExecutorService的execute和submit方法的更多相关文章

  1. ExecutorService的submit方法使用

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

  2. 线程池提交任务的两种方式:execute与submit的区别

    Java中的线程池在进行任务提交时,有两种方式:execute和submit方法. 一.execute和submit的区别 execute只能提交Runnable类型的任务,无返回值.submit既可 ...

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

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

  4. 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)

    在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...

  5. 线程池 execute 和 submit 的区别

    代码示例: public class ThreadPool_Test { public static void main(String[] args) throws InterruptedExcept ...

  6. execute和submit的区别与联系

    execute和submit都属于线程池的方法,execute只能提交Runnable类型的任务,而submit既能提交Runnable类型任务也能提交Callable类型任务. execute会直接 ...

  7. AbstractExecutorService的submit方法概要介绍

    1.概述 ExecutorService是JDK提供的框架,它简化了异步模式下的任务执行.一般来说,ExecutorService会自动提供一个线程池和API,用于为其分配任务. 2.实例化Execu ...

  8. ExecutorService——shutdown方法和awaitTermination方法

    ExecutorService的关闭shutdown和awaitTermination为接口ExecutorService定义的两个方法,一般情况配合使用来关闭线程池. 方法简介shutdown方法: ...

  9. 答疑解惑之ExecutorService——shutdown方法和awaitTermination方法使用

    ExecutorService的关闭 shutdown和awaitTermination为接口ExecutorService定义的两个方法,一般情况配合使用来关闭线程池. shutdownnow和它的 ...

随机推荐

  1. 安卓 Activity Fragment 生命周期

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 活动:  创建->启动->获得焦点->暂停->停止->销毁 ...

  2. 91网漏洞打包#越权+爆破+存储xss可打cookie

    漏洞一.主站存在登录口爆破 抓包,爆破一下 爆破成功 漏洞二.检测app时一处存储xss 在app登录后 我要提问那里插入xss 然后弹窗 可以打到cookie 漏洞三.app个人资料处平行越权可查看 ...

  3. Java类实例化原理

    Java对象的创建过程包括 类初始化(JVM类加载机制)和类实例化两个阶段. 一.Java对象创建时机 (1)使用new关键字创建对象 (2)反射创建对象 使用Class类的newInstance方法 ...

  4. 解决XP系统访问Win10打印机被拒绝的问题

    打印机是办公室人员经常会用到的设备,为了方便多人使用都会将打印机设置共享,可是会有许多xp系统用户需要访问win10系统上的打印机,这时候却发现拒绝访问无法连接,该如何解决呢? 其实这是win10做的 ...

  5. C# 7.0中可能出现的语法

    今天在MSDN上看到的微软关于微软关于C# 7.0特性的Work List,主要特性如下: Tuple增强 Tuple的可读性一直不是很好, 很多时候宁愿新写一个类也不使用Item1, Item2这种 ...

  6. HDU 4498 Function Curve (分段,算曲线积分)

    Function Curve Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)To ...

  7. windows及linux下安装django simple captcha 遇到的各种问题及解决的方法

    转载自http://www.cnblogs.com/descusr/p/3225874.html 全部程序写完之后,验证码图片不显示,点击图片地址会提演示样例如以下错误,而且在linux下的纠正办法 ...

  8. JSP中Out和Request对象详解

    内置表示不需要new便可直接使用. 一.基础知识 1.缓冲区:IO最原始是一个一个字节的读取,这就像吃米饭的时候一粒一粒的吃,很没有效率,这时候就有了碗,一碗一碗的吃,岂不痛快. 2.Get提交不能超 ...

  9. UnsupportedOperationException:can&#39;t convert to dimension :typx=0x1

    at android.content.res.TypeArray.getDimensionPixelSize(TypeArray.java:463) 今天在给项目做适配执行项目时遇到这个错误,发生错误 ...

  10. sql server datetime类型字段使用isnull返回1900-01-01 00:00:00.000的问题

    若字段定义的类型为datetime,插入为''(空),那么会默认值为1900-01-01 00:00:00.000 解决方法查询的时候过滤下cast(nullif('','') as datetime ...