Java异步调用Future对象

Future类存在于JDK的concurrent包中,主要用途是接收Java的异步线程计算返回的结果。

个人理解的使用场景大概如下:

有两个任务A和B,A任务中仅仅需要使用B任务计算成果,有两种方法实现:

  1. A和B在同一个线程中顺序执行。即先执行B,得到返回结果之后再执行A。
  2. 开两个线程,A和B并行执行。当A需要B的计算结果时如果B还没有执行完,A既可以选择阻塞等待B执行完,也可以先做其他的工作,过一段时间后再询问一次B。

毫无疑问,如果B是一个耗时比较大的计算任务时,后者比前者的效率高了很多。

使用Java的Future对象的实现。

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

public class FutureDemo {
    
    public static void main(String[] args) {
        
        ExecutorService threadPool = Executors.newCachedThreadPool();
        Future<Integer> future = threadPool.submit(new Callable<Integer>() {  
            public Integer call() throws Exception {  
                Thread.sleep(3000);
                return new Random().nextInt(100);  
            }  
        }); 
        
        doSomething();
        
        try {  
            System.out.println("is B done : " + future.isDone());
            System.out.println("result of B : " + future.get());
            System.out.println("is B done : " + future.isDone());
            int result = future.get();
            
            doSomethingWithB(result);
        } 
        catch (InterruptedException e) {  
            e.printStackTrace();  
        } 
        catch (ExecutionException e) {  
            e.printStackTrace();  
        } 
        System.exit(0);
    }

    private static void doSomethingWithB(int result) {
        // TODO Auto-generated method stub
        
    }

    private static void doSomething() {
        // TODO Auto-generated method stub
        
    }

}

输出结果:

is B done : false
result of B : 25
is B done : true

Future对象使用get方法获取线程的返回值,即call方法的返回值。

不带参数的get方法是阻塞方法,只要线程为返回结果就会一直阻塞直到有结果为止。

可以使用isDone方法判断线程是否结束。也可以使用带参数的get方法,若指定时间内还没有得到线程返回值,会抛出TimeoutException的异常。

该方法源码:

/**
     * Waits if necessary for at most the given time for the computation
     * to complete, and then retrieves its result, if available.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
原文地址:https://www.cnblogs.com/4everlove/p/4277270.html