`

ExecutorCompletionService分析及使用

阅读更多

ExecutorCompletionService分析及使用

 

当我们通过Executor提交一组并发执行的任务,并且希望在每一个任务完成后能立即得到结果,有两种方式可以采取:

 

方式一:

通过一个list来保存一组future,然后在循环中轮训这组future,直到每个future都已完成。如果我们不希望出现因为排在前面的任务阻塞导致后面先完成的任务的结果没有及时获取的情况,那么在调用get方式时,需要将超时时间设置为0 

Java代码  收藏代码
  1. public class CompletionServiceTest {  
  2.   
  3.     static class Task implements Callable<String>{  
  4.         private int i;  
  5.           
  6.         public Task(int i){  
  7.             this.i = i;  
  8.         }  
  9.   
  10.         @Override  
  11.         public String call() throws Exception {  
  12.             Thread.sleep(10000);  
  13.             return Thread.currentThread().getName() + "执行完任务:" + i;  
  14.         }     
  15.     }  
  16.       
  17.     public static void main(String[] args){  
  18.         testUseFuture();  
  19.     }  
  20.       
  21.     private static void testUseFuture(){  
  22.         int numThread = 5;  
  23.         ExecutorService executor = Executors.newFixedThreadPool(numThread);  
  24.         List<Future<String>> futureList = new ArrayList<Future<String>>();  
  25.         for(int i = 0;i<numThread;i++ ){  
  26.             Future<String> future = executor.submit(new CompletionServiceTest.Task(i));  
  27.             futureList.add(future);  
  28.         }  
  29.                   
  30.         while(numThread > 0){  
  31.             for(Future<String> future : futureList){  
  32.                 String result = null;  
  33.                 try {  
  34.                     result = future.get(0, TimeUnit.SECONDS);  
  35.                 } catch (InterruptedException e) {  
  36.                     e.printStackTrace();  
  37.                 } catch (ExecutionException e) {  
  38.                     e.printStackTrace();  
  39.                 } catch (TimeoutException e) {  
  40.                     //超时异常直接忽略  
  41.                 }  
  42.                 if(null != result){  
  43.                     futureList.remove(future);  
  44.                     numThread--;  
  45.                     System.out.println(result);  
  46.                     //此处必须break,否则会抛出并发修改异常。(也可以通过将futureList声明为CopyOnWriteArrayList类型解决)  
  47.                     break;  
  48.                 }  
  49.             }  
  50.         }  
  51.     }  
  52. }  

 方式二:

第一种方式显得比较繁琐,通过使用ExecutorCompletionService,则可以达到代码最简化的效果。

Java代码  收藏代码
  1. public class CompletionServiceTest {  
  2.   
  3.     static class Task implements Callable<String>{  
  4.         private int i;  
  5.           
  6.         public Task(int i){  
  7.             this.i = i;  
  8.         }  
  9.   
  10.         @Override  
  11.         public String call() throws Exception {  
  12.             Thread.sleep(10000);  
  13.             return Thread.currentThread().getName() + "执行完任务:" + i;  
  14.         }     
  15.     }  
  16.       
  17.     public static void main(String[] args) throws InterruptedException, ExecutionException{  
  18.         testExecutorCompletionService();  
  19.     }  
  20.       
  21.     private static void testExecutorCompletionService() throws InterruptedException, ExecutionException{  
  22.         int numThread = 5;  
  23.         ExecutorService executor = Executors.newFixedThreadPool(numThread);  
  24.         CompletionService<String> completionService = new ExecutorCompletionService<String>(executor);  
  25.         for(int i = 0;i<numThread;i++ ){  
  26.             completionService.submit(new CompletionServiceTest.Task(i));  
  27.         }  
  28. }  
  29.           
  30.         for(int i = 0;i<numThread;i++ ){       
  31.             System.out.println(completionService.take().get());  
  32.         }  
  33.           
  34.     }  

 

ExecutorCompletionService分析:

 CompletionService是Executor和BlockingQueue的结合体。

Java代码  收藏代码
  1. public ExecutorCompletionService(Executor executor) {  
  2.         if (executor == null)  
  3.             throw new NullPointerException();  
  4.         this.executor = executor;  
  5.         this.aes = (executor instanceof AbstractExecutorService) ?  
  6.             (AbstractExecutorService) executor : null;  
  7.         this.completionQueue = new LinkedBlockingQueue<Future<V>>();  
  8.     }  

 任务的提交和执行都是委托给Executor来完成。当提交某个任务时,该任务首先将被包装为一个QueueingFuture,

Java代码  收藏代码
  1. public Future<V> submit(Callable<V> task) {  
  2.         if (task == nullthrow new NullPointerException();  
  3.         RunnableFuture<V> f = newTaskFor(task);  
  4.         executor.execute(new QueueingFuture(f));  
  5.         return f;  
  6.     }  

 QueueingFutureFutureTask的一个子类,通过改写该子类的done方法,可以实现当任务完成时,将结果放入到BlockingQueue中。

 

Java代码  收藏代码
  1. private class QueueingFuture extends FutureTask<Void> {  
  2.         QueueingFuture(RunnableFuture<V> task) {  
  3.             super(task, null);  
  4.             this.task = task;  
  5.         }  
  6.         protected void done() { completionQueue.add(task); }  
  7.         private final Future<V> task;  
  8.     }  

 而通过使用BlockingQueue的take或poll方法,则可以得到结果。在BlockingQueue不存在元素时,这两个操作会阻塞,一旦有结果加入,则立即返回。

Java代码  收藏代码
  1. public Future<V> take() throws InterruptedException {  
  2.     return completionQueue.take();  
  3. }  
  4.   
  5. public Future<V> poll() {  
  6.     return completionQueue.poll();  
  7. }  

 

http://xw-z1985.iteye.com/blog/1997077

 

分享到:
评论

相关推荐

    Callable,Future的使用方式

    Callable,Future的使用方式,里面使用了三种使用方式分别是FutureTask,ExecutorService,ExecutorCompletionService

    多线程相关代码(新)

    包括阻塞队列、阻塞栈、ExecutorService、Future、ExecutorCompletionService、死锁、join、重入锁、读写锁、多线程抢票、信号量、signal/await、ThreadLocal等的实例。

    rockyou.txt

    rockyou

    ASP+ACCESS网上人才信息管理系统(源代码+论文)【ASP】.zip

    ASP+ACCESS网上人才信息管理系统(源代码+论文)【ASP】

    河北金融学院经济大数据课设2024年 软科学校爬虫课设

    河北金融学院经济大数据课设2024年 软科学校爬虫课设

    widgetsnbextension-4.0.0b0-py3-none-any.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    协同过滤服务+源代码+文档说明

    - 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

    基于ASP公交在线查询系统设计(源代码+论文)【ASP】.zip

    基于ASP公交在线查询系统设计(源代码+论文)【ASP】

    ASP.NET某中学图书馆系统的设计与实现(源代码+论文)【ASP】.zip

    ASP.NET某中学图书馆系统的设计与实现(源代码+论文)【ASP】

    ASP.NET猜数游戏的设计与开发(源代码+论文)【ASP】.zip

    ASP.NET猜数游戏的设计与开发(源代码+论文)【ASP】

    asp.net师电子化信息库的设计与实现(源代码+论文)【ASP】.zip

    asp.net师电子化信息库的设计与实现(源代码+论文)【ASP】

    2023-04-06-项目笔记 - 第一百五十六阶段 - 4.4.2.154全局变量的作用域-154 -2024.06.06

    2023-04-06-项目笔记-第一百五十六阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.154全局变量的作用域_154- 2024-06-06

    哈尔滨工程大学833社会研究方法2020考研专业课初试大纲.pdf

    哈尔滨工程大学考研初试大纲

    grpcio-1.27.2-cp36-cp36m-win_amd64.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    基于Java的大学生综合评测系统(源码+论文+数据库文件+演示视频).zip

    系统可以实现的功能有: 管理员: 用户管理:对管理员信息进行管理。 班级信息管理:添加和修改,管理班级信息,包括对班级人数,班主任姓名进行管理。 科目信息管理: 对科目的学时,学分,类型进行管理。 教师信息管理:管理教师的基本信息。 学生信息管理:学生班级,姓名,性别,电话,密码等信息进行管理。 学生成绩管理:普通成绩,德育加分,干部加分等成绩。 综合查询:通过学号和姓名,查询学生的平均成绩,干部,德育分数和总分。 普通管理员(教师) 班级信息管理:添加和修改,管理班级信息,包括对班级人数,班主任姓名进行管理。 科目信息管理: 对科目的学时,学分,类型进行管理。 教师信息管理:管理教师的基本信息。 学生信息管理:学生班级,姓名,性别,电话,密码等信息进行管理。 学生成绩管理:普通成绩,德育加分,干部加分等成绩。 综合查询:通过学号和姓名,查询学生的平均成绩,干部,德育分数和总分。 学生 个人资料:修改个人资料信息。 自我评价:对自己的基本情况进行评价。 综合查询:对个人的成绩,学年,课程的成绩进行查询,并能打印。

    ASP.NET+SQL房地产管理系统设计与实现(开题报告+源代码+论文+任务书+工作总结+答辩PPT)【ASP】.zip

    ASP.NET+SQL房地产管理系统设计与实现(开题报告+源代码+论文+任务书+工作总结+答辩PPT)【ASP】

    基于python+pyqt5开发的俄罗斯方块游戏源码+使用说明.zip

    基于python+pyqt5开发的俄罗斯方块游戏源码+使用说明.zip基于python+pyqt5开发的俄罗斯方块游戏源码+使用说明.zip 【优质项目推荐】 1.项目代码功能经验证ok,确保稳定可靠运行。欢迎下载使用!在使用过程中,如有问题或建议,请及时私信沟通,帮助解答。 2.项目主要针对各个计算机相关专业,包括计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师或企业员工使用。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、项目初期立项演示等用途。 4.如果基础还行,或热爱钻研,可基于此项目进行二次开发,DIY其他不同功能。 功能 播放音乐 暂停游戏 消除方块的音效 窗口自由拖拽 游戏存档 安装和运行 ### 1. 使用`pip` ```shell # csdn下载此项目源码解压重命名为PyQt5-Tetris(不要有中文路径) 进入到项目 cd PyQt5-Tetris # 使用pip安装依赖 pip install -r requirements.txt # 运行 python main.py ``` ### 2. 使用`pipenv` ```shell # csdn下载此项目源码解压重命名为PyQt5-Tetris(不要有中文路径) # 进入到项目 cd PyQt5-Tetris # 使用pipenv安装依赖 pipenv sync # 运行 pipenv run start ``` ### 3. 按键说明 - `A` - 向左移动 - `D`- 向右移动 - `W` - 变形 - `S` - 加速下降 - `P` - 暂停 - `ESC` - 退出程序 ## PyInstaller 打包 ### 1. 使用`pip` ```shell # 安装依赖 pip install -r requirements-dev.txt # 打包,打包成功之后exe文件在dist文件夹下 pyinstaller main.spec ``` ### 2. 使用`pipenv` ```shell # 安装依赖 pipenv install --dev # 打包,打包成功之后exe文件在dist文件夹下 pipenv run build ```

    cryptography-3.4.7-cp36-abi3-macosx_10_10_x86_64.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    华为OD机试华为OD机试华为OD机试2024最新最全真题

    2024版华为OD机试题库,包含C、D卷所有真题,粉丝可领取体验卡免费看题,包含面试手撕代码等等内容

Global site tag (gtag.js) - Google Analytics