JUC中Executor基本知识
Future And Callable
引用
http://www.cnblogs.com/dolphin0520/p/3949310.html
http://www.iocoder.cn/JUC/
Future用于返回任务,带有返回值

Callable和Runnable 的区别
Runnable是在JDK1.0版本引入的,唯一的一个方法是void run()。多插入一句,JDK设计者设计的类是真的强从1.0用到现在还在用
Callable是在JDK1.5版本引入的,唯一的一个方法是void call()和Runnable中的void run()对应,Callable是做为Executor实际调用的对象,尽管会经过复杂的封装,比如FutureTask继承于RunnabFuture,而RunnaFuture继承了Runnable和Future,并且Executor实际调用的是executor( Runnable run);也就是调用Runnable对象,但实际上FutureTask中的void run方法实际上会调用FutureTask中Callable callable属性的call()方法。是不是很晕<<<
为什么是Callable而不是Runnable
返回值需要进行泛型约束,来避免代码编写的强制转型。对于Callable接口增加了<V>作为返回值
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
如果直接使用原来的Runnable进行约束的话会导致ExecutorService返回的值为Object类型,需要在代码里进行强制转化,这可能会抛出转换异常。
所以ExecutorService中为Runnable提供了两个submit方法其中一种带有泛型
/*带泛型*/
<T> Future<T> submit(Runnable task, T result);
/*不带泛型*/
Future<?> submit(Runnable task);
Executor继承体系

Executor
java.util.concurrent.Executor ,任务的执行者接口,线程池框架中几乎所有类都直接或者间接实现 Executor 接口,它是线程池框架的基础。
Executor 提供了一种将“任务提交”与“任务执行”分离开来的机制,它仅提供了一个 #execute(Runnable command) 方法,用来执行已经提交的 Runnable 任务。代码如下:
public interface Executor {
void execute(Runnable command);
}
Executor中的四个状态
创建(create)->提交(submit)->开始(start)->完成(finish)
ExcutorService
java.util.concurrent.ExcutorService ,继承 Executor 接口,它是“执行者服务”接口,它是为”执行者接口 Executor “服务而存在的。准确的地说,ExecutorService 提供了”将任务提交给执行者的接口( submit 方法)”,”让执行者执行任务( invokeAll , invokeAny 方法)”的接口等等。代码如下:
public interface ExecutorService extends Executor {
/**
* 启动一次顺序关闭,执行以前提交的任务,但不接受新任务
*/
void shutdown();
/**
* 试图停止所有正在执行的活动任务,暂停处理正在等待的任务,并返回等待执行的任务列表
*/
List<Runnable> shutdownNow();
/**
* 如果此执行程序已关闭,则返回 true。
*/
boolean isShutdown();
/**
* 如果关闭后所有任务都已完成,则返回 true
*/
boolean isTerminated();
/**
* 请求关闭、发生超时或者当前线程中断,无论哪一个首先发生之后,都将导致阻塞,直到所有任务完成执行
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
// ========== 提交任务 ==========
/**
* 提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future
*/
<T> Future<T> submit(Callable<T> task);
/**
* 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future
*/
<T> Future<T> submit(Runnable task, T result);
/**
* 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future
*/
Future<?> submit(Runnable task);
/**
* 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
/**
* 执行给定的任务,当所有任务完成或超时期满时(无论哪个首先发生),返回保持任务状态和结果的 Future 列表
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
/**
* 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
/**
* 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
AbstractExecutorService
java.util.concurrent.AbstractExecutorService ,抽象类,实现 ExecutorService 接口,为其提供默认实现。
AbstractExecutorService 除了实现 ExecutorService 接口外,还提供了 #newTaskFor(...) 方法,返回一个 RunnableFuture 对象,在运行的时候,它将调用底层可调用任务,作为 Future 任务,它将生成可调用的结果作为其结果,并为底层任务提供取消操作。
实际上都是转化为RunnableFuture类
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);
}
多种常用线程池
newFixedThreadPool
newFixedThreadPool将创建一个固定长度的线程池,每次提交一个任务时就创建一个线程,这时线程池的规模不再改变(如果发生了未预期的Exception而结束,那么线程池会补充一个新的线程。
newCachedThreadPool
newCachedThreadPool将创建一个可缓存的线程池,如果线程池的当前规模超过了处理需求时,那么将回收空闲的线程,当需求增加时,则可以添加新的线程,线程的规模不存在任何限制,
newScheduledThreadPool
newFixedThreadPool
ScheduledExecutorService
java.util.concurrent.ScheduledExecutorService ,继承 ExecutorService ,为一个“延迟”和“定期执行”的 ExecutorService 。他提供了如下几个方法,安排任务在给定的延时执行或者周期性执行。代码如下:
// 创建并执行在给定延迟后启用的 ScheduledFuture。
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
// 创建并执行在给定延迟后启用的一次性操作。
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
// 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;
//也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
// 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
JUC中Executor基本知识的更多相关文章
- 跟着阿里p7一起学java高并发 - 第19天:JUC中的Executor框架详解1,全面掌握java并发核心技术
这是java高并发系列第19篇文章. 本文主要内容 介绍Executor框架相关内容 介绍Executor 介绍ExecutorService 介绍线程池ThreadPoolExecutor及案例 介 ...
- java高并发系列 - 第20天:JUC中的Executor框架详解2之ExecutorCompletionService
这是java高并发系列第20篇文章. 本文内容 ExecutorCompletionService出现的背景 介绍CompletionService接口及常用的方法 介绍ExecutorComplet ...
- rxjava源码中的线程知识
rxjava源码中的线程知识 rx的最精简的总结就是:异步 这里说一下以下的五个类 1.Future2.ConcurrentLinkedQueue3.volatile关键字4.AtomicRefere ...
- java高并发系列 - 第25天:掌握JUC中的阻塞队列
这是java高并发系列第25篇文章. 环境:jdk1.8. 本文内容 掌握Queue.BlockingQueue接口中常用的方法 介绍6中阻塞队列,及相关场景示例 重点掌握4种常用的阻塞队列 Queu ...
- java高并发系列 - 第26篇:学会使用JUC中常见的集合,常看看!
这是java高并发系列第26篇文章. 环境:jdk1.8. 本文内容 了解JUC常见集合,学会使用 ConcurrentHashMap ConcurrentSkipListMap Concurrent ...
- [转载]JavaEE学习篇之——网络传输数据中的密码学知识以及Tomcat中配置数字证书EE
原文链接:http://blog.csdn.net/jiangwei0910410003/article/details/21716557 今天是学习JavaWeb的第二天,我们来了解什么呢?就了解一 ...
- thinkPHP 模板中的语法知识 详细介绍(十二)
原文:thinkPHP 模板中的语法知识 详细介绍(十二) 本章节:介绍模板中的语法,详细的语法介绍 一.导入CSS和JS文件 ==>记住常量的是大写 1.css link .js sc ...
- JUC学习笔记--JUC中并发工具类
JUC中并发工具类 CountDownLatch CountDownLatch是我目前使用比较多的类,CountDownLatch初始化时会给定一个计数,然后每次调用countDown() 计数减1, ...
- RSA原理、ssl认证、Tomcat中配置数字证书以及网络传输数据中的密码学知识
情形一:接口的加.解密与加.验签 rsa不是只有加密解密,除此外还有加签和验签.之前一直误以为加密就是加签,解密就是验签.这是错误的! 正确的理解是: 数据传输的机密性:公钥加密私钥解密是密送,保 ...
随机推荐
- css继承和层叠
在前面介绍了如何利用文档结构和css选择器为元素应用各种丰富的样式,今天来好好聊聊css的层叠和继承,先说说概念. 继承:一个元素向其后代元素传递属性值所采用的机制,说的通俗点,就是元素的某些属性可以 ...
- confd test
vi /etc/confd/confd.toml backend = "consul"confdir = "/etc/confd"log-level = &qu ...
- binary tree
一.中序线索化 二叉树节点定义: class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; int isle ...
- SpringBoot简单理解
SpringBoot 一.特点:1.默认大于配置,不需要大量配置文件,没有web.xml,拥有可运行的Application类. 2.一般通过java代码配置,而尽量少使用xml配置. 3.maven ...
- 映射文件中增删改查标签中的parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中. resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射 ...
- Qt的安装和使用中的常见问题(详细版)
对于太长不看的朋友,可参考Qt的安装和使用中的常见问题(简略版). 目录 1.引入 2.Qt简介 3.Qt版本 3.1 查看安装的Qt版本 3.2 查看当前项目使用的Qt版本 3.3 查看当前项目使用 ...
- [DT] 数据结构术语中英文对照
数据结构术语中英文对照 数据 Data 数据元素 Data element 数据项 Data item 数据结构 Data structure 逻辑结构 Logical structure 数据类型 ...
- Solr分词搜索结果不准确
Solr的schema.xml默认配置分词后条件取 OR 例如:大众1.6T 系统会自动分词为 [大众] [1.6T](ps:不同分词器分词效果不同) 会搜索出包含 [大众 OR 1.6T] ...
- Oracle GoldenGate 一、介绍和安装
1 说明 1.1 下载和文档说明 下载地址:http://www.oracle.com/technetwork/middleware/goldengate/downloads/index.html 我 ...
- 莫队算法详解和c实现
解析和实现 摘要: 莫队算法是一个对于区间.树或其他结构离线(在线)维护的算法,此算法基于一些基本算法,例如暴力维护,树状数组,分块,最小曼哈顿距离生成树,对其进行揉合从而产生的一个简单 ...