Java异步调用Future对象
Future类存在于JDK的concurrent包中,主要用途是接收Java的异步线程计算返回的结果。
个人理解的使用场景大概如下:
有两个任务A和B,A任务中仅仅需要使用B任务计算成果,有两种方法实现:
- A和B在同一个线程中顺序执行。即先执行B,得到返回结果之后再执行A。
- 开两个线程,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;
posted on 2015-02-06 15:30 Allen Blue 阅读(7165) 评论(0) 编辑 收藏 举报