java异步计算Future的使用(转)

从jdk1.5开始我们可以利用Future来跟踪异步计算的结果。在此之前主线程要想获得工作线程(异步计算线程)的结果是比较麻烦的事情,需要我们进行特殊的程序结构设计,比较繁琐而且容易出错。有了Future我们就可以设计出比较优雅的异步计算程序结构模型:根据分而治之的思想,我们可以把异步计算的线程按照职责分为3类:

1. 异步计算的发起线程(控制线程):负责异步计算任务的分解和发起,把分解好的任务交给异步计算的work线程去执行,发起异步计算后,发起线程可以获得Futrue的集合,从而可以跟踪异步计算结果

2. 异步计算work线程:负责具体的计算任务

3. 异步计算结果收集线程:从发起线程那里获得Future的集合,并负责监控Future的状态,根据Future的状态来处理异步计算的结果。

以下是我根据上述想法写的一个例子:

package com.chengxuyuanzhilu.two;

import java.util.List;
import java.util.concurrent.Future;

public class OutputResult implements Runnable {

    private FutureContext<String> context;

    public void setFutureContext(FutureContext<String> context){
        this.context = context;
    }

    @Override
    public void run() {
        System.out.println("start to output result:");
        List<Future<String>> list = this.context.getFutureList();

        for (Future<String> future : list) {
            this.outputResultFromFuture(future);
        }
        System.out.println("finish to output result.");
    }

    private void outputResultFromFuture(Future<String> future){
        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();
        };
    }

}
package com.chengxuyuanzhilu.two;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

public class FutureContext<T> {
    private List<Future<T>> futureList = new ArrayList<>();

    public  void addFuture(Future<T> future){
        this.futureList.add(future);
    }

    public List<Future<T>> getFutureList(){
        return this.futureList;
    }
}
package com.chengxuyuanzhilu.two;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AsyncController {
    //线程池
    private ExecutorService executorService;

    //保存异步计算的Future
    private FutureContext<String> context;

    public AsyncController() {
        //创建一个固定大小的线程池
        this.executorService = Executors.newFixedThreadPool(100);
        this.context = new FutureContext<>();
    }

    public static void main(String[] args) {
        //启动异步计算
        AsyncController controller = new AsyncController();
        controller.startAsycCompution();

        //启动异步计算结果输出线程,该线程扫描异步计算Futrue的状态,如果已经完成,则输出异步计算结果
        OutputResult output = new OutputResult();
        output.setFutureContext(controller.getFutureContext());
        Thread resultThread = new Thread(output);
        resultThread.start();
    }

    public FutureContext<String> getFutureContext(){
        return this.context;
    }

    public void startAsycCompution(){
        /**
         * 开启100个异步计算,每个异步计算线程随机sleep几秒来模拟计算耗时
         */
        final Random random = new Random();

        for (int i = 0; i < 100; i++) {
            Future<String> future = this.executorService.submit(
                    new Callable<String>(){

                        @Override
                        public String call() throws Exception {
                            int randomInt = random.nextInt(10);
                            Thread.sleep(randomInt * 1000);
                            return "" + randomInt;
                        }

                    });
            //每个异步计算的结果 存放在context中
            this.context.addFuture(future);
        }
    }

}

源码下载地址:http://pan.baidu.com/s/1c1uuq5M

时间: 2025-02-01 15:55:38

java异步计算Future的使用(转)的相关文章

Java并发编程实践:Callable异步回调Future、FutureTask用法

Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到.FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值,那么这个组合的使用有什么好处呢?假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这

14.Java中的Future模式

jdk1.7.0_79  本文实际上是对上文<13.ThreadPoolExecutor线程池之submit方法>的一个延续或者一个补充.在上文中提到的submit方法里出现了FutureTask,这不得不停止脚步将方向转向Java的Future模式. Future是并发编程中的一种设计模式,对于多线程来说,线程A需要等待线程B的结果,它没必要一直等待B,可以先拿到一个未来的Future,等B有了结果后再取真实的结果. ExecutorService executor = Executors.

13.FutureTask异步计算

FutureTask     1.可取消的异步计算,FutureTask实现了Future的基本方法,提供了start.cancel 操作,可以查询计算是否完成,并且可以获取计算     的结果.结果只可以计算完成之后去获取,get方法会阻塞当前计算没有完成的线程,一定计算完成则会立即释放. 线程池submit与execute     1.submit()可以传入参数为实现callable接口的实例,返回future实例对象.     2.execute()返回void. package dem

如何给ExecutorService异步计算设置超时

ExecutorService接口使用submit方法会返回一个Future<V>对象,Future表示异步计算的结果.它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果.计算完成后只能使用get方法来获取结果,如有必要,计算完成前可以阻塞此方法.取消则由cancel方法来执行.还提供了其他方法,以确定任务是正常完成还是被取消了.一旦计算完成,就不能再取消计算.如果为了可取消性而使用Future但又不提供可用的结果,则可以声明Future<?>形式类型.并返回nul

Java异步编程——深入源码分析FutureTask

Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识>.通过创建一个ThreadPoolExecutor,往里面丢任务就可以实现多线程异步执行了. 但之前的任务主要倾向于线程池,并没有讲到异步编程方面的内容.本文将通过介绍Executor+Future框架(FutureTask是实现的核心),来深入了解下Java的异步编程. 万事从示例开始,我们先通过示例D

并发编程之Callable异步,Future模式

Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口.然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果.我们一般只能采用共享变量或共享存储区以及线程通信的方式实现获得任务结果的目的. 不过,Java中,也提供了使用Callable和Future来实现获取任务结果的操作.Callable用来执行任务,产生结果,而Future用来获得结果. Callable接口的定义如下: public interface Callable<

你了解Java中的Future吗?

原文:https://www.jianshu.com/p/b8952f07ee5d 1.概述 在本文中,我们将了解Future.自Java 1.5以来一直存在的接口,在处理异步调用和并发处理时非常有用. 2.创建Future 简单地说,Future类表示异步计算的未来结果 - 这个结果最终将在处理完成后出现在Future中. 让我们看看如何编写创建和返回Future实例的方法. Future接口是长时间运行方法异步处理的理想选择.这使我们能够在等待Future封装的任务完成时执行一些其他事情.

收集的Java科学计算库

将数学.物理.生物.航天.经济学等的计算集成到单一系统架构,提供了细致全面的计算系统. 科学计算框架 Catalano http://www.oschina.net/p/catalano Catalano Framework 是一个 Java 和 Android 的科学计算框架. 主要计算功能: 图像处理 模糊逻辑 数学计算 统计 机器学习 神经网络 科学计算可移植扩展工具包 PETSc http://www.oschina.net/p/petsc PETSc(Portable, Extensi

Netty5源码分析(七) -- 异步执行Future和Promise

java.util.concurrent.Future是Java提供的接口,表示异步执行的状态,Future的get方法会判断任务是否执行完成,如果完成就返回结果,否则阻塞线程,直到任务完成. // Java FutureTask.get() public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); r