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中有可以返回值的线程吗?在具体的用法你知道吗?如果两 ...
随机推荐
- So easy Webservice 3.使用HttpClient工具调用Webservice接口
首先,看看webservice服务调用演示: a) 登录http://www.webxml.com.cn b) 单击手机查询服务 c) 选择要调用的方法 例如: getMobileCodeInfo 输 ...
- domion Designer 管理员ID过期
上班没几天,刚接触lotus domion 有一个服务器上打开相应的数据库提示 你的证书已经过期,网上找到的解决方案: ---------------------------------------- ...
- C运行时的数据结构
本文描述一下:C运行时的数据结构,相关的段,压栈等 unix默认的编译器会将编译生成的文件默认命名为a.out 目标文件和可执行文件可以有几种不同的格式,所有这些不同格式具有一个共同的概念,那就是段. ...
- JAVA中在Myeclipse里把表导入成相应的poco实体类
参考:地址: http://blog.csdn.net/jintaiyong/article/details/7383982
- 2013/7/17 HNU_训练赛5
sgu 542 Gena vs Petya sgu 543 Cafe 题意:有N组人需要被分配到某些固定了人数的桌子上,其中ai表示第i组有多少个人,安排作为需要符合如下安排:某一组的人员不能够单独在 ...
- iOS - AVPlayer 音视频播放
前言 NS_CLASS_AVAILABLE(10_7, 4_0) @interface AVPlayer : NSObject @available(iOS 4.0, *) public class ...
- iOS - Socket 网络套接字
1.Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket.Socket 又称 "套接字",应用程序通常通过 "套接字& ...
- MFC编程入门之五(MFC消息映射机制概述)
在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作.比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应. 一.什 ...
- eclipse设置字体、背景(豆绿)色、自动提示
背景色:(护眼豆绿色) window-->preferences-->General-->Editors-->Text Editors-->(最下遍一栏中的)Backgr ...
- 如何在大量jar包中搜索特定字符
欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...