Java并发编程二:Callable Future
来源:互联网 发布:有网络无法连接 编辑:程序博客网 时间:2024/06/03 12:33
概述
在jdk1.5之前,线程的创建有两种方式:一种是直接继承Thread,另外一种就是实现Runnable接口。
但这2种方式都存在一个问题就是:在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者消息传递的方式来达到效果,这样使用起来就比较麻烦。
从Java 1.5开始,就提供了Callable类和Future类,通过它们可以在任务执行完毕之后得到任务执行结果。经过分析和总结,我们把异步计算的线程按照职责分为3部分:
计算模型
1、控制器(Controller):异步计算的控制线程,负责异步计算任务的分解和发起,把分解好的任务交给异步计算的worker线程去执行,发起异步计算后,controller可以获得Futrue的集合,将集合数据传递给collector,collector根据Future的状态来处理异步计算的结果;
2、处理器(Wroker):异步计算线程,负责具体的计算任务;
3、结果收集器(Collector):异步计算结果收集线程,从发起线程那里获得Future的集合,并负责监控Future的状态,根据Future的状态来处理异步计算的结果。
根据以上模型,构建的异步计算代码如下:
控制器
package com.ips.concurrent.future;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/** * <p> * Title: TaskController * </p> * <p> * Description: 异步计算的控制线程(controller):负责异步计算任务的分解和发起,把分解好的任务交给异步计算的worker线程去执行,发起异步计算后, * controller可以获得Futrue的集合,将集合数据传递给collector,collector根据Future的状态来处理异步计算的结果。 * </p> * * @author liuzhibo * @date 2016年7月29日 */public class TaskController { ExecutorService executor = null; List<Future<Integer>> list = null; public TaskController() { executor = Executors.newFixedThreadPool(100); list = new ArrayList<Future<Integer>>(); } public void work() { System.out.println("Start processing : "); TaskWorker task = null; Future<Integer> future = null; for (int i = 0; i < 100; i++) { task = new TaskWorker(); future = this.executor.submit(task); list.add(future); } /** * 当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态,以后不能再往线程池中添加任何任务, * 否则将会抛出RejectedExecutionException异常。但是,此时线程池不会立刻退出,直到添加到线程池中的任务都已经处理完成 * ,才会退出。 与它相似的还有一个shutdownNow(),它通过调用Thread.interrupt来实现线程的立即退出。 **/ this.executor.shutdown(); System.out.println("Finish processing. "); } public void collect() { TaskCollector<Integer> task = new TaskCollector<Integer>(list); Thread thread = new Thread(task); thread.start(); } public static void main(String[] args) { // 定义异步计算的控制对象 TaskController controller = new TaskController(); // 启动异步计算任务 controller.work(); // 对异步计算结果进行收集 controller.collect(); }}
处理器
package com.ips.concurrent.future;import java.util.Random;import java.util.concurrent.Callable;/** * <p>Title: ProcessTask</p> * <p>Description: 异步计算线程(worker),负责具体的计算任务</p> * @author liuzhibo * @date 2016年7月29日 */public class TaskWorker implements Callable<Integer>{ final Random random = new Random(); @Override public Integer call() throws Exception { int randomInt = random.nextInt(10); Thread.sleep(randomInt * 1000); return randomInt; }}
收集器
package com.ips.concurrent.future;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Future;/** * <p> * Title: CollectTask * </p> * <p> * Description: 异步计算结果收集线程(collector),从发起线程那里获得Future的集合,并负责监控Future的状态, * 根据Future的状态来处理异步计算的结果。 * </p> * * @author liuzhibo * @date 2016年7月29日 */public class TaskCollector<T> implements Runnable { private List<Future<T>> list = new ArrayList<Future<T>>(); public TaskCollector(List<Future<T>> list) { this.list = list; } @Override public void run() { System.out.println("Start collecting : "); //由于Future的计算结果并不是按照list中的顺序进行返回的,以下代码存在性能问题,因此此处可以进行优化 for (Future<T> future : list) { try { while (true) { if (future.isDone() && !future.isCancelled()) { System.out.println("Future : " + future + ", Result : " + future.get()); break; } else { Thread.sleep(1000); } } } catch (Exception e) { e.printStackTrace(); } } System.out.println("Finish collecting."); }}
2 0
- Java并发编程二:Callable Future
- Java并发编程:Callable、Future
- java并发编程(8)--callable&Future
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- Java并发编程:Callable、Future和FutureTask
- NPOI导出数据到Word
- jquery的初始化的方法
- The All-purpose Zero
- EasyUI 日历
- 删除列表商品简单描述
- Java并发编程二:Callable Future
- Docker/compose分析
- Map遍历的两种方法对比
- Eclipse 中修改tomcat设置内存大小
- Java 中基本类型和包装类之间的转换
- Android自定义搜索框
- yii2 发邮件
- 【转】ES6-for-humans
- EasyUI 微调器