Java并发编程之CompletionService
来源:互联网 发布:淘宝转换率2.5正常么 编辑:程序博客网 时间:2024/05/17 22:20
当向Executor
提交多个任务并且希望获得它们在完成之后的结果,如果用FutureTask
,可以循环获取task
,并调用get
方法去获取task
执行结果,但是如果task
还未完成,获取结果的线程将阻塞直到task
完成,由于不知道哪个task优先执行完毕,使用这种方式效率不会很高。在jdk5时候提出接口
CompletionService
,它整合了Executor和BlockingQueue
的功能,可以更加方便在多个任务执行时获取到任务执行结果。
需求:不使用求和公式,计算从1到
1000000
相加的和。分析设计:需求指明不能使用求和公式,只能循环依次相加,为了提高效率,我们可以将1到
1000000
的数分为n段由n个task
执行,执行结束后merge结果求最后的和。代码实现:
- 声明
task
执行载体,线程池executor
; - 声明
CompletionService
,通过参数指定执行task
的线程池,存放已完成状态task
的阻塞队列,队列默认为基于链表结构的阻塞队列LinkedBlockingQueue
; - 调用
submit
方法提交task
; - 调用
take
方法获取已完成状态task
。
CompletionService
接口提供五个方法:
Future<V> submit(Callable<V> task)
提交Callable类型的task;Future<V> submit(Runnable task, V result)
提交Runnable类型的task;Future<V> take() throws InterruptedException
获取并移除已完成状态的task,如果目前不存在这样的task,则等待;Future<V> poll()
获取并移除已完成状态的task,如果目前不存在这样的task,返回null;Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException
获取并移除已完成状态的task
,如果在指定等待时间内不存在这样的task
,返回null
。
接下来我们来看看CompletionService
接口的具体实现:ExecutorCompletionService
。
- 成员变量
ExecutorCompletionService
有三个成员变量:
1. executor
:执行task的线程池,创建CompletionService
必须指定;
2. aes
:主要用于创建待执行task
;
3. completionQueue
:存储已完成状态的task
,默认是基于链表结构的阻塞队列LinkedBlockingQueue
。
- 构造方法
ExecutorCompletionService
提供两个构造方法,具体的使用具体情况具体分析,使用者可以根据业务场景来进行选择。
- task提交
ExecutorCompletionService
提供submit
方法来提交Callable
类型或者Runnable
类型的task
:
具体的执行流程如下:
- 参数校验,不符合条件的
task
抛出异常,程序结束; - 将
Callable
类型或者Runnable
类型的task
构造成FutureTask
; - 把构造好的
FutureTask
交由线程池executor
执行。
task
调用submit
方法可以提交,完成的task
是什么时候被加入到completionQueue
里的呢?针对这个问题,从submit
方法的源码可以看出,在提交到线程池的时候需要将FutureTask
封装成QueueingFuture
,我们来看
看QueueingFuture
的具体实现:
从源码可以看出,QueueingFuture
是FutureTask
的子类,实现了done
方法,在task执行完成之后将当前task
添加到completionQueue
,done
方法的具体调用在FutureTask
的finishCompletion
方法,上篇介绍FutureTask
的文章已经做过具体的分析,在这里就不再赘述了。
- 已完成状态task获取
CompletionService
的take
方法和poll
方法都可以获取已完成状态的task
,我们来看看具体的实现:
从源码可以看出,take
和poll
都是调用BlockingQueue
提供的方法。既然take
和poll
都可以获取到已完成状态的task
,那么他们的区别是什么呢?
take
在获取并移除已完成状态的task
时,如果目前暂时不存在这样的task
,等待,直到存在这样的task
;poll
在获取并移除已完成状态的task
时,如果目前暂时不存在这样的task
,不等待,直接返回null
。
- java并发编程之CompletionService
- Java并发编程之CompletionService
- Java并发编程-Executor框架之CompletionService
- Java并发编程:CompletionService
- Java并发编程系列之二十八:CompletionService
- JAVA并发编程--ExecutorService与CompletionService
- 并发编程中completionService
- java高并发之CompletionService优化多线程并发
- Java并发编程(Callable、Future和CompletionService)
- java并发编程学习-ExecutorService和CompletionService的区别
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- Java并发编程核心方法与框架-CompletionService的使用
- 使用CompletionService批处理任务(java并发编程第6章)
- Java并发编程举例Runnable, Callable, Future, FutureTask, CompletionService
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- Java并发编程与技术内幕:Callable、Future、FutureTask、CompletionService
- java concurrent之CompletionService
- [BZOJ]2648 SJY摆棋子 KD-Tree
- PHP下载服务器文件
- Java学习18 JDBC编程
- 二、基本数据类型
- 系统调用
- Java并发编程之CompletionService
- 群体遗传学--Fst指数
- SQL查询最近三个月的数据(查询最近几天,几年等等)
- 使用R,ggplot2绘制NMDS图
- Effective C++解析 Item3:尽量使用const
- MYSQL 查看最大连接数和修改最大连接数
- 线下演练,解决问题,线下再次演练,线上演练
- 机器学习之神经网络
- 判断用户是手机还是邮箱然后将中间替换为***