Java 线程池submit和execute
submit方法:
public abstract class AbstractExecutorService implements ExecutorService {
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
//....
}
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public class FutureTask<V> implements RunnableFuture<V> {
private final java.util.concurrent.FutureTask.Sync sync;
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new java.util.concurrent.FutureTask.Sync(callable);
}
public FutureTask(Runnable runnable, V result) {
sync = new java.util.concurrent.FutureTask.Sync(Executors.callable(runnable, result));
}
//....
}
submit返回的最终是FutureTask对象
execute方法:
public interface Executor {
void execute(Runnable command);
}
具体的实现在ThreadPoolExecutor类中
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
submit内部调用execute
submit有返回值
submit方便exception处理
submit的demo:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
List<Future<String>> resultList = new ArrayList<Future<String>>(); // 创建10个任务并执行
for (int i = 0; i < 10; i++) {
// 使用ExecutorService执行Callable类型的任务,并将结果保存在future变量中
Future<String> future = executorService.submit(new TaskWithResult(i));
// 将任务执行结果存储到List中
resultList.add(future);
}
executorService.shutdown(); // 遍历任务的结果
for (Future<String> fs : resultList) {
try {
System.out.println(fs.get()); // 打印各个线程(任务)执行的结果
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
executorService.shutdownNow();
e.printStackTrace();
return;
}
}
}
}
class TaskWithResult implements Callable<String> {
private int id; public TaskWithResult(int id) {
this.id = id;
} /**
* 任务的具体过程,一旦任务传给ExecutorService的submit方法,则该方法自动在一个线程上执行。
*
* @return
* @throws Exception
*/
public String call() throws Exception {
System.out.println("call()方法被自动调用,干活!!! " + Thread.currentThread().getName());
if (new Random().nextBoolean())
throw new TaskException("Meet error in task." + Thread.currentThread().getName());
// 一个模拟耗时的操作
for (int i =9; i > 0; i--)
;
return "call()方法被自动调用,任务的结果是:" + id + " " + Thread.currentThread().getName();
}
} class TaskException extends Exception {
public TaskException(String message) {
super(message);
}
}
call()方法被自动调用,干活!!! pool-1-thread-5
call()方法被自动调用,干活!!! pool-1-thread-1
call()方法被自动调用,干活!!! pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-6
call()方法被自动调用,干活!!! pool-1-thread-6
call()方法被自动调用,干活!!! pool-1-thread-4
call()方法被自动调用,干活!!! pool-1-thread-2
call()方法被自动调用,干活!!! pool-1-thread-3
call()方法被自动调用,干活!!! pool-1-thread-7
call()方法被自动调用,任务的结果是:0 pool-1-thread-1
call()方法被自动调用,任务的结果是:1 pool-1-thread-2
java.util.concurrent.ExecutionException: com.company.TaskException: Meet error in task.pool-1-thread-3
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at com.company.Main.main(Main.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.company.TaskException: Meet error in task.pool-1-thread-3
at com.company.TaskWithResult.call(Main.java:56)
at com.company.TaskWithResult.call(Main.java:40)
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)
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的更多相关文章
- 血的教训--如何正确使用线程池submit和execute方法
血的教训之背景:使用线程池对存量数据进行迁移,但是总有一批数据迁移失败,无异常日志打印 凶案起因 听说parallelStream并行流是个好东西,由于日常开发stream串行流的场景比较多,这次 ...
- Java线程池ThreadPoolExecuter:execute()原理
一.线程池执行任务的流程 如果线程池工作线程数<corePoolSize,创建新线程执行task,并不断轮训t等待队列处理task. 如果线程池工作线程数>=corePoolSize并且等 ...
- 并发编程(十二)—— Java 线程池 实现原理与源码深度解析 之 submit 方法 (二)
在上一篇<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中提到了线程池ThreadPoolExecutor的原理以及它的execute方法.这篇文章是接着上一篇文章 ...
- Java线程池使用和分析(二) - execute()原理
相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...
- Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- 【Java线程池快速学习教程】
1. Java线程池 线程池:顾名思义,用一个池子装载多个线程,使用池子去管理多个线程. 问题来源:应用大量通过new Thread()方法创建执行时间短的线程,较大的消耗系统资源并且系统的响应速度变 ...
- Java线程池学习
Java线程池学习 Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java ...
- java线程池的使用与详解
java线程池的使用与详解 [转载]本文转载自两篇博文: 1.Java并发编程:线程池的使用:http://www.cnblogs.com/dolphin0520/p/3932921.html ...
- java线程池分析和应用
比较 在前面的一些文章里,我们已经讨论了手工创建和管理线程.在实际应用中我们有的时候也会经常听到线程池这个概念.在这里,我们可以先针对手工创建管理线程和通过线程池来管理做一个比较.通常,我们如果手工创 ...
随机推荐
- Java Filter过滤xss注入非法参数的方法
http://blog.csdn.NET/feng_an_qi/article/details/45666813 Java Filter过滤xss注入非法参数的方法 web.xml: <filt ...
- Windows平台下解决Oracle12c使用PDB数据库创建SDE的问题 分类: oracle sde 2015-06-12 11:03 88人阅读 评论(0) 收藏
Windows平台下解决Oracle12c使用PDB数据库创建SDE的问题 Oracle 12C中引入了CDB与PDB的新特性,在ORACLE 12C数据库引入的多租用户环境(Multitenant ...
- Windows的445端口(文件共享)
周鸿祎:教育网大量电脑445端口暴露,导致中招_科技_腾讯网 http://tech.qq.com/a/20170513/016133.htm 互联网周鸿祎2017-05-13 12:04 据36 ...
- navicat导入数据出现中文乱码
1.问题描述: excel转为csv后,导入英文时没错.但中文就是显示的乱码. 2.解决方法: 将csv用记事本打开,调整编码格式为UTF-8, 点击保存覆盖掉原文件,然后再 导入,乱码问题就解决
- 三种方案在Windows系统下安装ubuntu双系统
一.虚拟机安装(不推荐) 使用工具:Vmware 如果不是因为迫不得已,比如Mac OS对硬件不兼容,Federa安装频繁出错,各种驱动不全等等,不推荐使用虚拟机安装. 个人感觉这是一种对操作系统的亵 ...
- python基础-第六篇-6.1生成器与迭代器
迭代器 特点: 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容 不能随机访问集合中的某个值 ,只能从头到尾依次访问 访问到一半时不能往回退 便于循环比较大的数据集合,节省 ...
- 009-mac下记事本工具 sublime text3
1.subline text3 下载:https://download.sublimetext.com/Sublime%20Text%20Build%203143.dmg 序列号:[来源与互联网,如有 ...
- Java-小技巧-004-jdk时间,jdk8时间,joda,calendar,获取当前时间前一周、前一月、前一年的时间
1.推荐使用java8 localdate等 线程安全 支持较好 地址 2.joda 一.简述 查看SampleDateFormat源码,叙述有: * Date formats are not syn ...
- Sails 框架学习资料
一介布衣 http://yijiebuyi.com/so.html?k=sails sails modules 模型自带的方法介绍 2016-09-06 929 nodejs查看更多 node.j ...
- css图片上悬浮文字(丝带效果)实现
首先看效果 思路:1.去掉“丝带“菱角使用的是overflow: hidden; 2.通过z-index降低图片的优先级或者调高“丝带”优先级来实现覆盖效果(z-index需要写在有position的 ...