Future的理解

public interface Future{

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

boolean isDone();

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;

}

Future的实现类FutureTask特点:回调函数done()方法,当一个任务执行结束后,会回调这个done()方法,我们可以在done()方法中调用FutureTask的get()方法来获得计算的结果。在其他时候get()会阻塞我的UI线程。

局限性:                                                                                                                                                                    Future:主要是获取任务执行结果和对异步任务的控制。1、但是如果是批量任务的话,获取执行结果很麻烦。因为不知道哪一个任务先完成,得不停的遍历查询。2、也因为Future.get是阻塞方法,使用不当会造成线程浪费。

解决方法:

1、批量任务中查询已完成任务,可以使用completionService,它提供了一个take()阻塞方法,用来获取所有已完成的任务。

2、对于第二个问题,可以用 Google Guava 库所提供的 ListeningExecutorService 和 ListenableFuture 来解决。ListenableFuture可以允许注册回调方法(callbacks),在运算(多线程执行)完成的时候进行调用,  或者在运算(多线程执行)完成后立即执行。

Future 在高并发环境下有可能重复提交任务的,所以需要FutureTask阻止这种情况发生,保证只会执行一次。将FutureTask放入map之中,用键值对保存。

FutureTask是一个RunnableFuture,继承Runnable、future,所以FutureTask可以提交给 Executor执行也可以由调用线程直接执行FutureTask.run()方法。FutureTask的run()方法中又会调用Callable的call()方法。

那为什么FutureTask还要继承Runnable呢?                                                                                                      Callable与Runnable:描述的都是抽象的计算任务。Runnable有局限性,虽然能将结果写入日志文件或者某个方式共享数据结构,但是不能返回一个值或者抛出异常;Callable是对Runnable局限性的弥补。

public interface RunnableFuture extends Runnable, Future{

}

private volatile intstate;

private static final intNEW=0;新建

private static final intCOMPLETING=1;执行中

private static final intNORMAL=2;正常

private static final intEXCEPTIONAL=3;异常

private static final intCANCELLED=4;取消

private static final intINTERRUPTING=5;中断中

private static final intINTERRUPTED=6;被中断

state的状态变化可以有四种方式

NEW->COMPLETING->NORMAL                            正常完成的流程

NEW->COMPLETING->EXCEPTIONAL                出现异常的流程

NEW->CANCELED                                                  被取消

NEW->INTERRUNPING->INTERRRUNPTED        被中断

你可能感兴趣的