submit方法:

  1. public abstract class AbstractExecutorService implements ExecutorService {
  2.  
  3. protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
  4. return new FutureTask<T>(runnable, value);
  5. }
  6.  
  7. protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
  8. return new FutureTask<T>(callable);
  9. }
  10.  
  11. public Future<?> submit(Runnable task) {
  12. if (task == null) throw new NullPointerException();
  13. RunnableFuture<Void> ftask = newTaskFor(task, null);
  14. execute(ftask);
  15. return ftask;
  16. }
  17.  
  18. public <T> Future<T> submit(Runnable task, T result) {
  19. if (task == null) throw new NullPointerException();
  20. RunnableFuture<T> ftask = newTaskFor(task, result);
  21. execute(ftask);
  22. return ftask;
  23. }
  24.  
  25. public <T> Future<T> submit(Callable<T> task) {
  26. if (task == null) throw new NullPointerException();
  27. RunnableFuture<T> ftask = newTaskFor(task);
  28. execute(ftask);
  29. return ftask;
  30. }
  31. //....
  32. }
  1. public interface RunnableFuture<V> extends Runnable, Future<V> {
  2. /**
  3. * Sets this Future to the result of its computation
  4. * unless it has been cancelled.
  5. */
  6. void run();
  7. }
  1. protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
  2. return new FutureTask<T>(runnable, value);
  3. }
  4.  
  5. protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
  6. return new FutureTask<T>(callable);
  7. }
  1. public class FutureTask<V> implements RunnableFuture<V> {
  2.  
  3. private final java.util.concurrent.FutureTask.Sync sync;
  4.  
  5. public FutureTask(Callable<V> callable) {
  6. if (callable == null)
  7. throw new NullPointerException();
  8. sync = new java.util.concurrent.FutureTask.Sync(callable);
  9. }
  10.  
  11. public FutureTask(Runnable runnable, V result) {
  12. sync = new java.util.concurrent.FutureTask.Sync(Executors.callable(runnable, result));
  13. }
  14. //....
  15. }

submit返回的最终是FutureTask对象

execute方法:

  1. public interface Executor {
  2.  
  3. void execute(Runnable command);
  4. }

具体的实现在ThreadPoolExecutor类中

  1. public void execute(Runnable command) {
  2. if (command == null)
  3. throw new NullPointerException();
  4.  
  5. int c = ctl.get();
  6. if (workerCountOf(c) < corePoolSize) {
  7. if (addWorker(command, true))
  8. return;
  9. c = ctl.get();
  10. }
  11. if (isRunning(c) && workQueue.offer(command)) {
  12. int recheck = ctl.get();
  13. if (! isRunning(recheck) && remove(command))
  14. reject(command);
  15. else if (workerCountOf(recheck) == 0)
  16. addWorker(null, false);
  17. }
  18. else if (!addWorker(command, false))
  19. reject(command);
  20. }

submit内部调用execute

submit有返回值

submit方便exception处理

submit的demo:

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

Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

http://blog.csdn.net/yuzhiboyi/article/details/7775266

http://blog.csdn.net/zhangzhaokun/article/details/6615454

http://blog.csdn.net/xtwolf008/article/details/7713580

Java 线程池submit和execute的更多相关文章

  1. 血的教训--如何正确使用线程池submit和execute方法

    血的教训之背景:使用线程池对存量数据进行迁移,但是总有一批数据迁移失败,无异常日志打印 凶案起因 ​ 听说parallelStream并行流是个好东西,由于日常开发stream串行流的场景比较多,这次 ...

  2. Java线程池ThreadPoolExecuter:execute()原理

    一.线程池执行任务的流程 如果线程池工作线程数<corePoolSize,创建新线程执行task,并不断轮训t等待队列处理task. 如果线程池工作线程数>=corePoolSize并且等 ...

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

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

  4. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

  5. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  6. 【Java线程池快速学习教程】

    1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...

  7. Java线程池学习

    Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...

  8. java线程池的使用与详解

    java线程池的使用与详解 [转载]本文转载自两篇博文:  1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html   ...

  9. java线程池分析和应用

    比较 在前面的一些文章里,我们已经讨论了手工创建和管理线程.在实际应用中我们有的时候也会经常听到线程池这个概念.在这里,我们可以先针对手工创建管理线程和通过线程池来管理做一个比较.通常,我们如果手工创 ...

随机推荐

  1. 解决;R语言使用sqldf库是报错"Failed to connect to database: Error: Access denied for user '..'@'localhost' (using password: NO) Error in !dbPreExists : invalid argument type"

    原因:在使用sqldf时,不需要加载RMySQL库 解决方案:在控制台执行释放RMySQL库加载 detach("package:RMySQL", unload=T);

  2. Macbook pro 13" Installs Ubuntu 18.04

    最新版的 MacBook对Ubuntu的支持(或者反过来?)不是很好,但是除了Suspend和resume功能没找到方法使用外,其他都还好,可用. 1.mac在OSX中先安装refind引导,如果开启 ...

  3. php格式化输出数组

    写网页的时候经常需要在页面中打印数组,但格式特别难看,看看一个html神器吧<pre>标签,能非常标准的显示数组格式 使用的时候只需要这样打印你的数组就OK了,太好用了,神器! echo ...

  4. mybatis调用oracle存储过程例子.

    1.MYBATIS方法: <select id="getFlowNum" statementType="CALLABLE"> <![CDATA ...

  5. 前端开发 - CSS - 下

    CSS: 12.display 13.浮动效果 14.浮动特性 15.浮动产生的问题和解决方法 16.float京东导航栏 17.position 18.z-index 19.京东案例 12.disp ...

  6. (0.2.4)Mysql安装——yum源安装

    转自:https://www.cnblogs.com/jimboi/p/6405560.html Centos6.8通过yum安装mysql5.7 1.下载好对应版本的yum源文件 2.安装用来配置m ...

  7. 006-Shell printf 命令

    一.概述 printf 命令模仿 C 程序库(library)里的 printf() 程序. printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好. pr ...

  8. java 多线程 day09 线程池

    import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...

  9. SDUT2857:艺术联合会(简单dp)

    链接: http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2857 题目解析: 这是去年校赛的题目, ...

  10. windows平台mongoDB安装配置

    一.首先安装mongodb 1.官网下载mongoDB:http://www.mongodb.org/downloads,选择windows平台.安装时,一路next就可以了.我安装在了F:\mong ...