CompletionService 使用小结
本文为博主原创,转载请注明出处:
实现异步任务时,经常使用 FutureTask 来实现;一个简单的示例代码如下:
public static void main(String[] args) throws ExecutionException, InterruptedException {
//构建线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
FutureTask<Integer> futureTask1 = (FutureTask<Integer>) executorService.submit(()->doTask1());
FutureTask<Integer> futureTask2 = (FutureTask<Integer>) executorService.submit(()->doTask2()); // 获取电结果并异步保存
executorService.execute(()->save(futureTask1.get()));
// 获取结果并异步保存
executorService.execute(()->save(futureTask2.get()); }
上面代码如果 futureTask1 的任务需要执行很长时间,而 futureTask2 执行很短时间,上面代码在执行的过程中,futureTask2 任务的执行也的先等 futureTask1.get() 执行结束后 ,才能保存 futureTask2.get() ;因为这个主线程都阻塞在 futureTask1.get() 的操作上;严重降低了效率。
此时可以使用 CompletionService 来解决这个问题
CompletionService 接口的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样就可以将执行任务与处理任务分离开。
CompletionService的一个实现是ExecutorCompletionService,它是Executor和BlockingQueue功能的融合体,Executor完成计算任务,BlockingQueue负责保存异步任务的执行结果;先执行完的先进入阻塞队列,利用这个特性,你可以轻松实现后续处理的有序性,避免无谓的等待。在执行大量相互独立和同构的任务时,可以使用CompletionService;
该实现类定义的三个属性:
在类的注释上有使用的示例,可以参考学习
使用 CompletionService 实现的示例如下:
public static void main(String[] args) {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
// 创建CompletionService
CompletionService<Integer> cs = new ExecutorCompletionService<>(executor);
// 用于保存Future对象
List<Future<Integer>> futures = new ArrayList<>(3);
//提交异步任务,并保存future到futures
futures.add(cs.submit(()->doTask1()));
futures.add(cs.submit(()->doTask2()));
futures.add(cs.submit(()->doTask3()));
// 获取最快返回的任务执行结果
Integer r = 0;
try {
// 只要有一个成功返回,则break
for (int i = 0; i < 3; ++i) {
r = cs.take().get();
//简单地通过判空来检查是否成功返回
if (r != null) {
break;
}
}
} finally {
//取消所有任务
for(Future<Integer> f : futures)
f.cancel(true);
}
// 返回结果
}
CompletionService 使用小结的更多相关文章
- 计算机程序的思维逻辑 (79) - 方便的CompletionService
上节,我们提到,在异步任务程序中,一种常见的场景是,主线程提交多个异步任务,然后希望有任务完成就处理结果,并且按任务完成顺序逐个处理,对于这种场景,Java并发包提供了一个方便的方法,使用Comple ...
- Java编程的逻辑 (79) - 方便的CompletionService
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- 那些年读过的书《Java并发编程实战》和《Java并发编程的艺术》三、任务执行框架—Executor框架小结
<Java并发编程实战>和<Java并发编程的艺术> Executor框架小结 1.在线程中如何执行任务 (1)任务执行目标: 在正常负载情况下,服务器应用 ...
- Java并发编程系列之二十八:CompletionService
CompletionService简介 CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而C ...
- CompletionService简介、原理以及小案例
博客1:http://www.oschina.net/question/12_11255 博客2: CompletionService简介 CompletionService与ExecutorServ ...
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- Python自然语言处理工具小结
Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...
- java单向加密算法小结(2)--MD5哈希算法
上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...
- iOS--->微信支付小结
iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...
- iOS 之UITextFiled/UITextView小结
一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...
随机推荐
- 【项目实战】用Pytorch实现线性回归
视频教程:https://www.bilibili.com/video/BV1Y7411d7Ys?p=5 准备数据 首先配置了环境变量,这里使用python3.9.7版本,在Anaconda下构建环境 ...
- kvm使用桥接的方法
什么是桥接 桥接就是把物理机的网卡模拟成交换机,虚拟机的网卡直接连在虚拟的网桥即交换机上.这样kvm虚拟机分配的IP地址,就应该和物理机在同一网段,可以对外进行服务. 在KVM下运行的VM默认的网卡采 ...
- kibana知识点
1.Kibana 有 Linux.Darwin 和 Windows 版本的安装包.由于 Kibana 基于 Node.js 运行,我们在这些平台上包含了一些必要的 Node.js 二进制文件.Kiba ...
- 官方使用logstash同步Mysql数据表到ES的摘抄
官方文档地址:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html#plugins-inputs-jdbc ...
- MySQL一致性读原来是有条件的
众所周知,在设定了隔离等级为Repeatable Read及以上时,InnoDB 可以实现数据的一致性读.换句话来说,就是事务执行的任意时刻,读取到的数据是同一个快照,不会受到其他事务的更新影响. 以 ...
- Go 源码解读|如何用好 errors 库的 errors.Is() 与 errors.As() 方法
前言 快一个月没有更新技术文章了,这段时间投注了较多的时间学习字节的开源项目 Kitex/Hertz ,并维护一些简单的 issue ,有兴趣的同学也可以去了解: https://www.cloudw ...
- python运行以及入门语法基础
pycharm下载与使用 1.pycharm官网下载(直接到pycharm下载地址) http://www.jetbrains.com/pycharm/download/#section=window ...
- 自己动手写ls命令——Java版
自己动手写ls命令--Java版 介绍 在前面的文章Linux命令系列之ls--原来最简单的ls这么复杂当中,我们仔细的介绍了关于ls命令的使用和输出结果,在本篇文章当中我们用Java代码自己实现ls ...
- 2022牛客OI赛前集训营-提高组(第一场) 奇怪的函数 根号很好用
奇怪的函数 考虑暴力,每次查询\(O(n)\)扫所有操作,修改\(O(1)\) 这启发我们平衡复杂度,考虑分块. 观察题目性质,可以发现,经过若干次操作后得到的结果一定是一个关于\(x\)的分段函数, ...
- 自建流媒体如何录制视频。齐博x1齐博x2齐博x3齐博x4齐博x5齐博x6齐博x7齐博x8齐博x9齐博x10
http://x1.eapis.site/ 先打开配置文件\conf\config.php 里边的内容大概如下,第一项是必须要配置的,换成你的网站域名网址.第二项,如果流媒体服务器配置了https证书 ...