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


一、execute和submit的区别
- execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
- execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。
测试代码:
package com.javaBase.LineDistancePond; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 〈一句话功能简述〉;
* 〈execute与submit的区别〉
*
* @author jxx
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TestThreadPoolBegin { public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newSingleThreadExecutor();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Runnable线程处理开始...");
int a = 0;
int b = 3;
System.out.println("除以0的结果为:" + b/a);
System.out.println("Runnable线程处理结束...");
}
};
es.execute(runnable);
es.shutdown();
}
}
执行结果:
Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
Runnable线程处理开始...
at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.run(TestThreadPoolBegin.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745) Process finished with exit code 0
package com.javaBase.LineDistancePond; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 〈一句话功能简述〉;
* 〈execute与submit的区别〉
*
* @author jxx
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TestThreadPoolBegin { public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newSingleThreadExecutor();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Runnable线程处理开始...");
int a = 0;
int b = 3;
System.out.println("除以0的结果为:" + b/a);
System.out.println("Runnable线程处理结束...");
}
};
es.submit(runnable);
es.shutdown();
}
}
执行结果:
Runnable线程处理开始... Process finished with exit code 0
package com.javaBase.LineDistancePond; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* 〈一句话功能简述〉;
* 〈execute与submit的区别〉
*
* @author jxx
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TestThreadPoolBegin { public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newSingleThreadExecutor();
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
System.out.println("线程处理开始...");
int a = 0;
int b = 3;
System.out.println("除以0的结果为:" + b/a);
System.out.println("线程处理结束...");
return "0";
}
};
Future<String> future = es.submit(callable);
System.out.println("任务执行完成,结果为:" + future.get());
}
}
执行结果:
Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.javaBase.LineDistancePond.TestThreadPoolBegin.main(TestThreadPoolBegin.java:32)
Caused by: java.lang.ArithmeticException: / by zero
at com.javaBase.LineDistancePond.TestThreadPoolBegin$1.call(TestThreadPoolBegin.java:26)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
线程处理开始...
二、submit的get方法
future的get方法在未获得返回值之前会一直阻塞,我们可以使用future的isDone方法判断任务是否执行完成,然后再决定是否get,因此上述代码我们可以优化如下:
package com.javaBase.LineDistancePond; import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; /**
* 〈一句话功能简述〉;
* 〈execute与submit的区别〉
*
* @author jxx
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TestThreadPoolBegin { public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newSingleThreadExecutor();
Callable callable = new Callable() {
@Override
public String call() throws Exception {
System.out.println("线程处理开始...");
int a = 2;
int b = 3;
System.out.println("3/2的结果为:" + b/a);
System.out.println("线程处理结束...");
return "0";
}
};
Future<String> future = es.submit(callable);
while(true) {
//idDone:如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
if(future.isDone()) {
System.out.println("任务执行完成:" + future.get());
break;
}
}
es.shutdown();
}
}
执行结果:
线程处理开始...
3/2的结果为:1
线程处理结束...
线程执行完成:0 Process finished with exit code 1
线程池提交任务的两种方式:execute与submit的区别的更多相关文章
- spark application提交应用的两种方式
bin/spark-submit --help ... ... --deploy-mode DEPLOY_MODE Whether to launch the driver program loc ...
- java中实现同步的两种方式:syschronized和lock的区别和联系
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ...
- SpringMVC实现Action的两种方式以及与Struts2的区别
4.程序员写的Action可采用哪两种方式? 第一.实现Controller接口第二.继承自AbstractCommandController接口 5.springmvc与struts2的区别? 第一 ...
- iOS两种方式加载图片的区别
加载图片的方式: imageNamed: imageWithContentsOfFile: 加载Assets.xcassets这里面的图片: 1> 打包后变成Assets.car 2> 拿 ...
- HTTP请求的两种方式get和post的区别
1,get从服务器获取数据:post向服务器发送数据: 2,安全性,get请求的数据会显示在地址栏中,post请求的数据放在http协议的消息体: 3,从提交数据的大小看,http协议本身没有限制数据 ...
- Virsh中创建虚拟机两种方式define和create的区别
本质上两者一样的,都是从xml配置文件创建虚拟机 define 丛xml配置文件创建主机但是不启动 create 同样是丛xml配置文件创建主机,但是可以指定很多选项,比如是否启动,是否连接控制台 ...
- (并发编程)进程池线程池--提交任务2种方式+(异步回调)、协程--yield关键字 greenlet ,gevent模块
一:进程池与线程池(同步,异步+回调函数)先造个池子,然后放任务为什么要用“池”:池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务池子内什么时候装进程:并发的任务 ...
- Android提交数据到服务器的两种方式四种方法
本帖最后由 yanghe123 于 2012-6-7 09:58 编辑 Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方 ...
- [操作系统知识储备,进程相关概念,开启进程的两种方式、 进程Queue介绍]
[操作系统知识储备,进程相关概念,开启进程的两种方式.进程Queue介绍] 操作系统知识回顾 为什么要有操作系统. 程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作 ...
随机推荐
- java连接到sql sever 2008_java基础学习
(sql sever 2008跟sql sever 2005装载JDBC驱动的方法是一样的) 一.加载驱动的文字教程 1.准备相关的软件(Eclipse除外,开源软件可以从官网下载) <1> ...
- 人工智能进度好慢,呜呜呜 还是先来学python!!!!!!!二十三讲、二十四讲!
0:十转2 def my_bin(x): a ='' if x : a = my_bin(x//2) return a+str(x%2) else: a+='0b' return a print(my ...
- Vue 源码解读(8)—— 编译器 之 解析(上)
特殊说明 由于文章篇幅限制,所以将 Vue 源码解读(8)-- 编译器 之 解析 拆成了上下两篇,所以在阅读本篇文章时请同时打开 Vue 源码解读(8)-- 编译器 之 解析(下)一起阅读. 前言 V ...
- Pytorch AdaptivePooing操作转Pooling操作
Pytorch AdaptivePooing操作转Pooling操作 多数的前向推理框架不支持AdaptivePooing操作,此时需要将AdaptivePooing操作转换为普通的Pooling操作 ...
- 【C# task】TaskContinuationOptions 位枚举
TaskContinuationOptions 根据 TaskContinuationOptions 的不同,出现了三个分支 LongRunning:独立线程,和线程池无关 包含 PreferFair ...
- 【C#IO 操作】字符流(StreamWriter、StreamReader)
StreamWaiter类和StreamReader类的用法 事实上, StreamReader为了性能的考虑, 在自己的内部内置并维护了一个byte buffer. 如果在声明StreamReade ...
- [源码解析] NVIDIA HugeCTR,GPU 版本参数服务器---(8) ---Distributed Hash之后向传播
[源码解析] NVIDIA HugeCTR,GPU 版本参数服务器---(8) ---Distributed Hash之后向传播 目录 [源码解析] NVIDIA HugeCTR,GPU 版本参数服务 ...
- 截图工具snipaste
下载地址: https://zh.snipaste.com/download.html 使用: 按F1截图,截图后按F3悬浮
- omnet++:官方文档翻译总结(二)
这一部分是官方案例介绍 1.Introduction 学习自:Introduction - OMNeT++ Technical Articles 本教程是基于Tictoc的仿真案例,这些案例我们可以在 ...
- C#10新特性-lambda 表达式和方法组的改进
C# 10 中对Lambda的语法和类型进行了多项改进: 1. Lambda自然类型 Lambda 表达式现在有时具有"自然"类型. 这意味着编译器通常可以推断出 lambda 表 ...