Java并发编程二:Callable Future

本文介绍了一种基于Java的异步计算模型,该模型利用了Java 1.5引入的Callable和Future接口来解决传统线程创建方式无法直接获取执行结果的问题。模型包括控制器(Controller)、处理器(Worker)和结果收集器(Collector)三个部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

在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.");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值