java并发带返回结果的批量任务执行
转载:http://www.it165.net/pro/html/201405/14551.html
一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的抽象,run方法中只能记录日志,打印,或者把数据汇总入某个容器(一方面内存消耗大,另一方面需要控制同步,效率很大的限制),总之不能返回执行的结果;比如同时1000个任务去网络上抓取数据,然后将抓取到的数据进行处理(处理方式不定),我觉得最好的方式就是提供回调接口,把处理的方式最为回调传进去;但是现在我们有了更好的方式实现:CompletionService + Callable
Callable的call方法可以返回执行的结果;
CompletionService将Executor(线程池)和BlockingQueue(阻塞队列)结合在一起,同时使用Callable作为任务的基本单元,整个过程就是生产者不断把Callable任务放入阻塞对了,Executor作为消费者不断把任务取出来执行,并返回结果;
优势:
a、阻塞队列防止了内存中排队等待的任务过多,造成内存溢出(毕竟一般生产者速度比较快,比如爬虫准备好网址和规则,就去执行了,执行起来(消费者)还是比较慢的)
b、CompletionService可以实现,哪个任务先执行完成就返回,而不是按顺序返回,这样可以极大的提升效率;
1、CompletionService : Executor + BlockingQueue
下面看个例子:
01.package com.zhy.concurrency.completionService;02. 03.import java.util.Random;04.import java.util.concurrent.BlockingQueue;05.import java.util.concurrent.Callable;06.import java.util.concurrent.CompletionService;07.import java.util.concurrent.ExecutionException;08.import java.util.concurrent.ExecutorCompletionService;09.import java.util.concurrent.ExecutorService;10.import java.util.concurrent.Executors;11.import java.util.concurrent.Future;12.import java.util.concurrent.LinkedBlockingDeque;13. 14./**15.* 将Executor和BlockingQueue功能融合在一起,可以将Callable的任务提交给它来执行, 然后使用take()方法获得已经完成的结果16.*17.* @author zhy18.*19.*/20.public class CompletionServiceDemo21.{22. 23.public static void main(String[] args) throws InterruptedException,24.ExecutionException25.{26./**27.* 内部维护11个线程的线程池28.*/29.ExecutorService exec = Executors.newFixedThreadPool(11);30./**31.* 容量为10的阻塞队列32.*/33.final BlockingQueue<Future<Integer>> queue = new LinkedBlockingDeque<Future<Integer>>(34.10);35.//实例化CompletionService36.final CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(37.exec, queue);38. 39./**40.* 模拟瞬间产生10个任务,且每个任务执行时间不一致41.*/42.for (int i = 0; i < 10; i++)43.{44.completionService.submit(new Callable<Integer>()45.{46.@Override47.public Integer call() throws Exception48.{49.int ran = new Random().nextInt(1000);50.Thread.sleep(ran);51.System.out.println(Thread.currentThread().getName()52.+ " 休息了 " + ran);53.return ran;54.}55.});56.}57. 58./**59.* 立即输出结果60.*/61.for (int i = 0; i < 10; i++)62.{63.try64.{ 65.//谁最先执行完成,直接返回66.Future<Integer> f = completionService.take();67.System.out.println(f.get());68.} catch (InterruptedException e)69.{70.e.printStackTrace();71.} catch (ExecutionException e)72.{73.e.printStackTrace();74.}75.}76. 77.exec.shutdown();78. 79.}80. 81.}输出结果:
01.pool-1-thread-4 休息了 5202.5203.pool-1-thread-1 休息了 5904.5905.pool-1-thread-10 休息了 21506.21507.pool-1-thread-9 休息了 35208.35209.pool-1-thread-5 休息了 38910.38911.pool-1-thread-3 休息了 58912.58913.pool-1-thread-2 休息了 79414.79415.pool-1-thread-7 休息了 80516.80517.pool-1-thread-6 休息了 90918.90919.pool-1-thread-8 休息了 98720.987最先执行完成的直接返回,并不需要按任务提交的顺序执行,如果需要写个高并发的程序,且每个任务需要返回执行结果,这是个相当不错的选择!
java并发带返回结果的批量任务执行的更多相关文章
- java并发带返回结果的批量任务执行(CompletionService:Executor + BlockingQueue)
转载:http://www.it165.net/pro/html/201405/14551.html 一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runnable是一种有很大局限的 ...
- Java并发专题 带返回结果的批量任务执行 CompletionService ExecutorService.invokeAll(转)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/27250059 一般情况下,我们使用Runnable作为基本的任务表示形式,但是R ...
- Java并发专题 带返回结果的批量任务执行
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/27250059 一般情况下,我们使用Runnable作为基本的任务表示形式,但是R ...
- 带返回结果的批量任务执行 CompletionService
转自 :http://blog.csdn.net/lmj623565791/article/details/27250059 一般情况下,我们使用Runnable作为基本的任务表示形式,但是Runna ...
- Android JNI之调用JAVA方法的返回类型签名
从http://blog.csdn.net/lonelyroamer/article/details/7932787截取的 如何签名: 下面看看Sign签名如何写,来表示要取得的属性或方法的类型. 1 ...
- 在Java 线程中返回值的用法
http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread 有时在执行线程中需要在线程中返回一个值:常规中我们 ...
- java 异常处理与返回
try{ // 1. return ++x; }catch(){ }finally{ //2. x++; } 实际返回值还是 ++x后的结果,因为 ++x 后 x 的值会入栈,作为返回结果: 以上代码 ...
- java 代码执行cmd 返回值异常 (关于JAVA Project.waitfor()返回值是1)
关于JAVA Project.waitfor()返回值是1 0条评论 Project.waitfor()返回值是1,找了很久从网上没有发现关于1的说明. 这时对源代码调试了一下,发现Project ...
- Java多线程带返回值的Callable接口
Java多线程带返回值的Callable接口 在面试的时候,有时候是不是会遇到面试会问你,Java中实现多线程的方式有几种?你知道吗?你知道Java中有可以返回值的线程吗?在具体的用法你知道吗?如果两 ...
随机推荐
- CSS笔记(三)背景
CSS 允许应用纯色作为背景,也允许使用背景图像创建相当复杂的效果. 参考:http://www.w3school.com.cn/css/css_background.asp 背景色 p {backg ...
- FLASH CC 2015 CANVAS 导出图片出现缩放问题
最近有项目 没时间更新教程 刚才出现一个问题 就是导出动画后,发现有图片无故被缩放(与软件内的设置不一样) 经过排查 发现动画师 直接将位图 进行了缩放, 导出后出现问题 把文图转换为影片剪辑后,做缩 ...
- Domion OA 日记
我现在使用的是IBM的 Lotus Dimion 8.5 以下内容是个人的浅显了解,在此记录下,已作为后续记录的翻看 第一次接触文档型数据库,确实颠覆了我对数据模型的认知,我之前一直用sql的 文档型 ...
- MongoDB资料汇总
MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. 它的特点是高性能.易部署.易使用,存储数据非常方便.主要功能特性有: 面向集合存 ...
- 四十条测试你是不是合格的PHP程序员
四十条测试你是否合格的PHP程序员,不官方,也不权威,但很给力.超过三条就不合格了.超过五条就得好好反省下自己的不足了. 1. 不会利用如phpDoc这样的工具来恰当地注释你的代码 2. 对优秀的集成 ...
- 阿里云大数据三次技术突围:Greenplum、Hadoop和“飞天”
阿里云大数据三次技术突围:Greenplum.Hadoop和"飞天" 对于企业来说,到底什么是云计算?相信很多企业都有这样的困惑,让我们一起回到这个原始的起点探讨究竟什么是云 ...
- php提示:Call to undefined function curl_init
我要利用curl函数进行数据采集时发现提示Call to undefined function curl_init错误了,后来从官网了解到因为curl默认不是php开启的函数,我们需要手工打开哦,下面 ...
- (三)ubuntu学习前传—uboot常见环境变量
1.环境变量如何参与程序运行(1)环境变量有2份,一份在Flash中,另一份在DDR中.uboot开机时一次性从Flash中读取全部环境变量到DDR中作为环境变量的初始化值,然后使用过程中都是用DDR ...
- Akka学习博客
http://www.iteblog.com/archives/1157 以示例介绍了actor模型.
- python语法笔记(四)
1.对象的属性 python一切皆对象,每个对象都可能有多个属性.python的属性有一套统一的管理方案. 属性的__dict__系统 对象的属性可能来自于其类定义,叫做类属性:还可能 ...