JDK线程池CompletionService的使用

最近使用多线程优化了一个非常耗时的ping任务,下面的是未优化的源代码,大致就是遍历es取出的list,然后循环判断是否能ping通:

SearchResponse searchResponse = client.search(searchRequest);
Iterator it = searchResponse.getHits().iterator();
while (it.hasNext()) {boolean isReachAble = false;SearchHit hit = (SearchHit) it.next();Link link = new Link();Map<String, Object> map = hit.getSourceAsMap();String area = (String) map.get("area");if ("上海".equals(area)) {//过滤掉上海地区continue;}List<String> getways = (List<String>) map.get("gateway");//一旦能连通其中任一网关则代表连接成功for (String getway : getways) {//这个isIpReachable很耗时if (isIpReachable(getway)) {isReachAble = true;break;}}link.setArea(area);link.setIsLink(isReachAble ? 1 : 0);links.add(link);
}

多线程的话现在基本都是直接使用线程池了吧,如下面第一行代码就能创建一个线程数为4的线程池:

ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletionService<String> pool = new ExecutorCompletionService<String>(executorService);

第二行的这个CompletionService是我们今天介绍的重点,它与默认的ExecutorService的最大区别就是:

通过executorService来submit的task不一定是按照加入自己维护的list顺序完成的;从list中遍历的每个Future对象并不一定处于完成状态,这时调用get()方法就会被阻塞住,如果系统是设计成每个线程完成后就能根据其结果继续做后面的事,这样对于处于list后面的但是先完成的线程就会增加了额外的等待时间。

而CompletionService的实现是维护一个保存Future对象的BlockingQueue。只有当这个Future对象状态是结束的时候,才会加入到这个Queue中,take()方法其实就是Producer-Consumer中的Consumer。它会从Queue中取出Future对象,如果Queue是空的,就会阻塞在那里,直到有完成的Future对象加入到Queue中。

所以,先完成的必定先被取出。这样就减少了不必要的等待时间

好了废话不多说,直接上优化后的代码:

//response中包含从es中取到的数据
SearchResponse searchResponse = client.search(searchRequest);
Iterator it = searchResponse.getHits().iterator();//创建固定数目线程的线程池
ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletionService<String> pool = new ExecutorCompletionService<String>(executorService);
List<Future<String>> resultList = new ArrayList<>();
while (it.hasNext()) {SearchHit hit = (SearchHit) it.next();Map<String, Object> map = hit.getSourceAsMap();List<String> getways = (List<String>) map.get("gateway");String area = (String) map.get("area");if ("上海".equals(area)) {//过滤掉上海地区continue;}//将耗时任务submit到线程池中resultList.add(pool.submit(() -> {long t1 = System.currentTimeMillis();boolean isReachAble = false;Link link = new Link();//一旦能连通其中任一网关则代表连接成功for (String getway : getways) {if (isIpReachable(getway)) {isReachAble = true;break;}}link.setArea((String) map.get("area"));link.setIsLink(isReachAble ? 1 : 0);links.add(link);long t2 = System.currentTimeMillis();return "task " + map.get("area") + " completed.耗时:" + (t2 - t1);}));
}
//如果没有下面的代码,主线程将直接返回
for(int i = 0; i < resultList.size(); i++){//在取到数据之前将会一直阻塞String result = pool.take().get();System.out.println(result);
}

我特地将单线程和多线程运行结果做了个对比,可以看到多线程优化过后时间减了一半之多

下面的是控制台输出,发现执行顺序确实基本是按时间由短到长,正好体现出了CompletionService的优点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/553696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win7系统应用程序安装不了的解决教程

软件是计算机数据和指令的集合&#xff0c;一般有系统软件和应用软件。系统是应用软件安装的平台&#xff0c;但是由于一些设置或者故障就会出现安装不了软件的情况&#xff0c;win7系统无法安装应用程序怎么解决?就此问题&#xff0c;下面就来跟大家聊聊win7系统应用程序安装…

解决mediawiki上传文件文件名是中文上传失败

公司内部的wiki是用的mediawiki&#xff0c;其它都还好就是上传文件时文件名中有中文就不能上传&#xff0c;这次下决心要修复这个问题&#xff0c;一开始我还以为是哪里需要配置一下&#xff0c;然后搜了半天发现这是一个官方的bug&#xff1a; 好吧&#xff0c;是官方bug也好…

win7系统字体模糊发虚不清晰的解决方法

如果我们使用的电脑操作系统是win7的话&#xff0c;当我们操作的时候发现系统的字体显示变得模糊发虚不清晰的情况不知道怎么解决的话&#xff0c;小编觉得我们可以先排查一下是自己电脑显示器的原因还是系统设置的问题。一般来说都是需要在电脑设置一下即可。详细解决步骤就来…

Elasticsearch Curator使用

介绍 Elasticsearch Curator通过以下方式帮助您策划或管理您的Elasticsearch索引和快照&#xff1a; 从集群中获取索引&#xff08;或快照&#xff09;的完整列表&#xff0c;作为可操作列表迭代用户定义的过滤器列表&#xff0c;根据需要逐步从此可操作列表中删除索引&#…

win7系统怎么更改语言及字体

win7系统中的字体和语言等&#xff0c;都是我们在使用电脑时&#xff0c;非常重要的东西&#xff0c;有部分用户们想要更改系统的默认的字体或者语言等&#xff0c;不知win7系统怎么更改语言及字体的话&#xff0c;就快来看看win7系统语言及字体等问题解决攻略吧~ win7系统怎么…

DHCP租用信息导出方案

方法一 使用“netsh dhcp server export”比“netsh dhcp server dump”的优点是export命令还将从DHCP服务器提取并存储活动租约信息(active lease information);这样&#xff0c;当我们恢复时&#xff0c;活动租约也会从该时间点恢复。 &#xff08;相反&#xff0c;dump命令…

windows7系统内存占用过高的解决方法

电脑的内存空间取决了电脑的运行流畅度&#xff0c;时间一久内存就会爆满导致占用过高这样就会使电脑变得延迟&#xff0c;那么windows7系统内存占用过高怎么办呢?下面就一起来看看windows7系统内存占用过高的解决方法吧。 windows7系统内存占用过高的解决方法&#xff1a; …

Metricbeat添加ip address信息

Metricbeat默认输出信息里没有ip地址&#xff0c;6.3版本之后可以通过add_host_metadata 来开启附带ip信息&#xff08;没测试过&#xff09; 原本我是通过修改modules.d/system.yml文件&#xff0c;在每项后面加自定义fields.ip字段来添加ip信息&#xff0c;类似下面这样&…

UC浏览器怎么清除缓存

UC浏览器怎么清除缓存 当我们的浏览器用久了&#xff0c;垃圾就多了&#xff0c;快点来让你的浏览器减减肥吧。以UC浏览器为例小编教大家怎么让你的浏览器减肥&#xff0c;甩掉不必要的垃圾。分享一篇UC浏览器清除缓存方法&#xff0c;希望能帮到大家 1、双击打开你的uc浏览器…

前端获取不了rest请求自定义headers的问题

前端response中的自定义header信息默认同一域中可见 在crossdomain跨域情况下需要在服务器端增加Access-Control-Expose-Headers的支持 例如在springboot中需要使用addExposedHeader添加指定返回头&#xff1a; Configuration public class CORSConfiguration implements WebM…

QQ浏览器如何添加并进入书签地址?QQ浏览器添加并进入书签地址的方法

打开手机“QQ浏览器”应用进入。 QQ浏览器如何添加并进入书签地址&#xff1f;QQ浏览器添加并进入书签地址的方法[多图] 进入主界面&#xff0c;选择或者搜索一个网页进入。 QQ浏览器如何添加并进入书签地址&#xff1f;QQ浏览器添加并进入书签地址的方法[多图] 进入相应网…

同时运行多个logstash而kibana监控界面只统计到一个的问题

问题 同时在36和39两台主机上启动了两个logstash&#xff0c;两台通过日志查看都正常运行&#xff0c;但是在Kibana的监控界面查看节点&#xff0c;发现统计结果只有一台 分析 logstash的monitor和management是统一交由xpack管理的&#xff0c;其中logstash的监控数据也会存…

浏览器的安全设置在哪里?要如何设置

所有的浏览器都有安全设置&#xff0c;安全的强度都是默认的&#xff0c;但是用户在浏览一些网站的时候就会出现无法打开的情况&#xff0c;出现这种情况一般都是因为浏览器的安全系数太高了&#xff0c;所有会自动阻拦用户访问网站的权限&#xff0c;那么浏览器的安全设置要如…

Vue cli3使用jQuery控件

背景介绍 由于历史遗留问题需要使用之前基于jQuery的代码&#xff0c;其中还用到了一个基于jQuery的多选控件&#xff0c;环境是vue cli3 导入并配置jQuery 首先通过npm导入jQuery npm install –save jquery修改package.json同级的vue.config.js文件(如果没有&#xff0c;…

火狐浏览器如何导入和导出书签收藏夹

火狐浏览器怎么导入和导出书签收藏夹?火狐浏览器是一款功能强大的浏览器&#xff0c;在使用浏览器时想要把书签收藏夹导出或导出到另外一个浏览器要怎么操作呢&#xff0c;下面就给大家分享具体步骤。 1、打开火狐浏览器&#xff0c;点击左上角“书签” 火狐浏览器如何导入和…

如何在搜狗浏览器中添加扩展工具

如何在搜狗浏览器中添加扩展工具?搜狗浏览器是一款比较好用的浏览器。我们在浏览网页的时候&#xff0c;需要添加一些外部的插件&#xff0c;具体该怎么添加呢?下面就是在搜狗浏览器中添加扩展工具的方法&#xff0c;一起了解一下。 1、打开搜狗浏览器&#xff0c;点击界面上…

谷歌浏览器如何设置flash访问权限

谷歌浏览器如何设置flash访问权限?最近有小伙伴向我询问谷歌浏览器中应该如何设置flash访问权限&#xff0c;今天小编就带给大家谷歌浏览器设置flash访问权限的操作步骤&#xff0c;让我们一起来看看吧。 方法/步骤 1、打开chrom浏览器&#xff0c;打开设置 谷歌浏览器如何…

win7旗舰版系统电脑没有声音怎么办

win7旗舰版系统电脑没有声音怎么办?近来有些win7旗舰版用户朋友遇到了一个奇怪的问题&#xff0c;昨天电脑还是好好的&#xff0c;今天打开电脑突然发现没有声音了&#xff0c;那么win7旗舰版没声音怎么修复呢?很多朋友不了解win7旗舰版系统电脑没有声音怎么修复&#xff0c;…

windows7如何实现屏幕不休眠

windows7如何实现屏幕不休眠&#xff1f;如果你还在被win7系统的快速休眠问题所困扰&#xff0c;那么快来看看小编今天为了解决win7系统屏幕休眠问题带来的屏幕不休眠设置方法&#xff0c;一起来看看windows7屏幕不休眠的设置方法吧。 windows7如何实现屏幕不休眠 1、点击右下…

win7系统还原失败怎么解决

一些使用win7系统的用户会遇到系统提示“更新失败还原更改”的情况&#xff0c;但是win7系统还原失败是是什么原因呢?,win7系统还原失败怎么办呢&#xff0c;这让许多用户感到很苦恼&#xff0c;不知道要怎么解决&#xff0c;下面我们就一起来看看win7系统还原失败解决方法。 …