Java中的线程池在进行任务提交时,有两种方式:execute和submit方法。

一、execute和submit的区别

  • execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
  • execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。

测试代码:

  1. package com.javaBase.LineDistancePond;
  2.  
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5.  
  6. /**
  7. * 〈一句话功能简述〉;
  8. * 〈execute与submit的区别〉
  9. *
  10. * @author jxx
  11. * @see [相关类/方法](可选)
  12. * @since [产品/模块版本] (可选)
  13. */
  14. public class TestThreadPoolBegin {
  15.  
  16. public static void main(String[] args) throws Exception{
  17. ExecutorService es = Executors.newSingleThreadExecutor();
  18. Runnable runnable = new Runnable() {
  19. @Override
  20. public void run() {
  21. System.out.println("Runnable线程处理开始...");
  22. int a = 0;
  23. int b = 3;
  24. System.out.println("除以0的结果为:" + b/a);
  25. System.out.println("Runnable线程处理结束...");
  26. }
  27. };
  28. es.execute(runnable);
  29. es.shutdown();
  30. }
  31. }

执行结果:

  1. Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
  2. Runnable线程处理开始...
  3. at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.run(TestThreadPoolBegin.java:24)
  4. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  5. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  6. at java.lang.Thread.run(Thread.java:745)
  7.  
  8. Process finished with exit code 0
  1. package com.javaBase.LineDistancePond;
  2.  
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5.  
  6. /**
  7. * 〈一句话功能简述〉;
  8. * 〈execute与submit的区别〉
  9. *
  10. * @author jxx
  11. * @see [相关类/方法](可选)
  12. * @since [产品/模块版本] (可选)
  13. */
  14. public class TestThreadPoolBegin {
  15.  
  16. public static void main(String[] args) throws Exception{
  17. ExecutorService es = Executors.newSingleThreadExecutor();
  18. Runnable runnable = new Runnable() {
  19. @Override
  20. public void run() {
  21. System.out.println("Runnable线程处理开始...");
  22. int a = 0;
  23. int b = 3;
  24. System.out.println("除以0的结果为:" + b/a);
  25. System.out.println("Runnable线程处理结束...");
  26. }
  27. };
  28. es.submit(runnable);
  29. es.shutdown();
  30. }
  31. }

执行结果:

  1. Runnable线程处理开始...
  2.  
  3. Process finished with exit code 0
  1. package com.javaBase.LineDistancePond;
  2.  
  3. import java.util.concurrent.Callable;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.Future;
  7.  
  8. /**
  9. * 〈一句话功能简述〉;
  10. * 〈execute与submit的区别〉
  11. *
  12. * @author jxx
  13. * @see [相关类/方法](可选)
  14. * @since [产品/模块版本] (可选)
  15. */
  16. public class TestThreadPoolBegin {
  17.  
  18. public static void main(String[] args) throws Exception{
  19. ExecutorService es = Executors.newSingleThreadExecutor();
  20. Callable callable = new Callable() {
  21. @Override
  22. public Object call() throws Exception {
  23. System.out.println("线程处理开始...");
  24. int a = 0;
  25. int b = 3;
  26. System.out.println("除以0的结果为:" + b/a);
  27. System.out.println("线程处理结束...");
  28. return "0";
  29. }
  30. };
  31. Future<String> future = es.submit(callable);
  32. System.out.println("任务执行完成,结果为:" + future.get());
  33. }
  34. }

执行结果:

  1. Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
  2. at java.util.concurrent.FutureTask.report(FutureTask.java:122)
  3. at java.util.concurrent.FutureTask.get(FutureTask.java:192)
  4. at com.javaBase.LineDistancePond.TestThreadPoolBegin.main(TestThreadPoolBegin.java:32)
  5. Caused by: java.lang.ArithmeticException: / by zero
  6. at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.call(TestThreadPoolBegin.java:26)
  7. at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  8. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
  9. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  10. at java.lang.Thread.run(Thread.java:745)
  11. 线程处理开始...

二、submit的get方法

  future的get方法在未获得返回值之前会一直阻塞,我们可以使用future的isDone方法判断任务是否执行完成,然后再决定是否get,因此上述代码我们可以优化如下:

  1. package com.javaBase.LineDistancePond;
  2.  
  3. import java.util.concurrent.Callable;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.Future;
  7.  
  8. /**
  9. * 〈一句话功能简述〉;
  10. * 〈execute与submit的区别〉
  11. *
  12. * @author jxx
  13. * @see [相关类/方法](可选)
  14. * @since [产品/模块版本] (可选)
  15. */
  16. public class TestThreadPoolBegin {
  17.  
  18. public static void main(String[] args) throws Exception{
  19. ExecutorService es = Executors.newSingleThreadExecutor();
  20. Callable callable = new Callable() {
  21. @Override
  22. public String call() throws Exception {
  23. System.out.println("线程处理开始...");
  24. int a = 2;
  25. int b = 3;
  26. System.out.println("3/2的结果为:" + b/a);
  27. System.out.println("线程处理结束...");
  28. return "0";
  29. }
  30. };
  31. Future<String> future = es.submit(callable);
  32. while(true) {
  33. //idDone:如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
  34. if(future.isDone()) {
  35. System.out.println("任务执行完成:" + future.get());
  36. break;
  37. }
  38. }
  39. es.shutdown();
  40. }
  41. }

执行结果:

  1. 线程处理开始...
  2. 3/2的结果为:1
  3. 线程处理结束...
  4. 线程执行完成:0
  5.  
  6. Process finished with exit code 1

线程池提交任务的两种方式:execute与submit的区别的更多相关文章

  1. spark application提交应用的两种方式

    bin/spark-submit --help ... ... --deploy-mode DEPLOY_MODE   Whether to launch the driver program loc ...

  2. java中实现同步的两种方式:syschronized和lock的区别和联系

    Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ...

  3. SpringMVC实现Action的两种方式以及与Struts2的区别

    4.程序员写的Action可采用哪两种方式? 第一.实现Controller接口第二.继承自AbstractCommandController接口 5.springmvc与struts2的区别? 第一 ...

  4. iOS两种方式加载图片的区别

    加载图片的方式: imageNamed: imageWithContentsOfFile: 加载Assets.xcassets这里面的图片: 1> 打包后变成Assets.car 2> 拿 ...

  5. HTTP请求的两种方式get和post的区别

    1,get从服务器获取数据:post向服务器发送数据: 2,安全性,get请求的数据会显示在地址栏中,post请求的数据放在http协议的消息体: 3,从提交数据的大小看,http协议本身没有限制数据 ...

  6. Virsh中创建虚拟机两种方式define和create的区别

    本质上两者一样的,都是从xml配置文件创建虚拟机 define  丛xml配置文件创建主机但是不启动 create  同样是丛xml配置文件创建主机,但是可以指定很多选项,比如是否启动,是否连接控制台 ...

  7. (并发编程)进程池线程池--提交任务2种方式+(异步回调)、协程--yield关键字 greenlet ,gevent模块

    一:进程池与线程池(同步,异步+回调函数)先造个池子,然后放任务为什么要用“池”:池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务池子内什么时候装进程:并发的任务 ...

  8. Android提交数据到服务器的两种方式四种方法

    本帖最后由 yanghe123 于 2012-6-7 09:58 编辑 Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方 ...

  9. [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]

    [操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...

随机推荐

  1. PON/产线测试解决方案

    第一章 方案背景与概述1.1 方案背景随着网络的高速发展与网络速率的不断提升,用户对网络产品的可靠性要求也越来 越高.网络产品的故障符合"浴盆曲线"规律,生产过程中的严格测试能够及 ...

  2. jprofiler 查看程序内存泄露

    在最近的工作中,通过JProfiler解决了一个内存泄漏的问题,现将检测的步骤和一些分析记录下来,已备今后遇到相似问题时可以作为参考. 运行环境: Tomcat6,jdk6,JProfiler8 内存 ...

  3. ABP 使用ElasticSearch、Kibana、Docker 进行日志收集

    ABP 使用ElasticSearch.Kibana.Docker 进行日志收集 后续会根据公司使用的技术,进行技术整理分享,都是干货哦别忘了关注我!!! 最近领导想要我把项目日志进行一个统一收集,因 ...

  4. Python:HTTP请求头headers信息的查询

    GET和POST请求后会返回一个response对象,可通过key.values等访问字典中元素的方式来访问该response对象headers中的各种属性 r=requests.get(url,he ...

  5. MySQL [ERROR] [MY-013183]

    [ERROR] [MY-013183] [InnoDB] Assertion failure,回顾记录一次因数据库(MySql 8.0)操作不当导致的生产事故顺便记录下正常重启发生的意外和解决方法(关 ...

  6. react的”Hello World !“

    本文主要简述react的开始使用 1.引入js文件 <!-- 1.核心文件 --> <script crossorigin src="https://unpkg.com/r ...

  7. doctor学习(二) - contos7安装doctor

    1.更新update到最新的版本 yum  update 2.卸载老版本docker yum  remove docker  docker-common docker-selinux  docker- ...

  8. Clickhouse 与 Kafka 的数据同步

    作者: LemonNan 原文地址: https://mp.weixin.qq.com/s/SUUHF9R_FKg-3vq7Q3cwBQ 注: 转载需注明作者及原文地址 介绍 Clickhouse 本 ...

  9. CF1117G题解

    题意:区间建笛卡尔树,求每个节点的siz之和. 首先看到笛卡尔树,就应该想到,因为这是一个排列,可以找到通过左边和右边第一个比自己大的元素来"建立"笛卡尔树. 设 \(l(u)\) ...

  10. [链表]LeetCode 25 K组一个翻转链表

    LeetCode 25 k组一个翻转链表 TITLE 示例 1: 输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5] 示例 2: 输入:head = [1,2,3, ...