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的区别的更多相关文章

  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. GAN实战笔记——第五章训练与普遍挑战:为成功而GAN

    训练与普遍挑战:为成功而GAN 一.评估 回顾一下第1章中伪造达・芬奇画作的类比.假设一个伪造者(生成器)正在试图模仿达・芬奇,想使这幅伪造的画被展览接收.伪造者要与艺术评论家(判别器)竞争,后者试图 ...

  2. 决策树CART回归树——算法实现

    决策树模型 选择最好的特征和特征的值进行数据集划分 根据上面获得的结果创建决策树 根据测试数据进行剪枝(默认没有数据的树分支被剪掉) 对输入进行预测 模型树 import numpy as np de ...

  3. layout_gravity和gravity

    layout_gravity是指控件本身的位置,gravity是指控件内元素的位置.

  4. Qt:QVector

    0.说明 template <typename T> class QVector QVector是存储同一个类型T数据的模板类,其功能是动态数组,数据在其中的存储是一系列连续的存储空间. ...

  5. python3中map()函数用法

    python源码解释如下:map(func, *iterables) --> map objectMake an iterator that computes the function usin ...

  6. Go基础知识梳理(四)

    Go基础知识梳理(四) GO的哲学是"不要通过共享内存来通信,而是通过通信来共享内存",通道是GO通过通信来共享内存的载体. rumtime包常用方法 runtime.NumGor ...

  7. 怎么在linux上安装部署jenkins

    怎么在linux上安装部署jenkins 作为一个非科班出身自学的小白,踩过很多的坑,特此留下记录 以下在虚拟机上示例 系统:linux(centos7) 操作方式:xshell连接终端操作 教程之前 ...

  8. SQL从零到迅速精通【查询利器】

    1.[列选取]从fruits表中获取f_name和f_price两列,T-SQL语句如下. SELECT f_name,f_price FROM fruits; 2.[去重]查询fruits表中s_i ...

  9. CSAPP-Lab04 Architecture Lab 深入解析

    穷且益坚,不坠青云之志. 实验概览 Arch Lab 实验分为三部分.在 A 部分中,需要我们写一些简单的Y86-64程序,从而熟悉Y86-64工具的使用:在 B 部分中,我们要用一个新的指令来扩展S ...

  10. tp6 验证方式

    think验证方式