Guava ListenableFuture
与JDK自带的Future相比,ListenableFuture提供一个当执行完成时的异步回调方法,addListener(Runnable, Executor)。 用Future的地方最好能用ListenableFuture来代替
创建ListenableFuture的方法
- 通过ListeningExecutorService.submit()
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)); ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() { public Explosion call() { return pushBigRedButton(); } }); Futures.addCallback(explosion, new FutureCallback<Explosion>() { public void onSuccess(Explosion explosion) { walkAwayFrom(explosion); } public void onFailure(Throwable thrown) { battleArchNemesis(); // escaped the explosion! } });
- 如果原来用的是FutureTask,可通过ListenableFutureTask.create(Callable<V>)或ListenableFutureTask.create(Runnable, V)来生成ListenableFutureTask,ListenableFutureTask是ListenableFuture的实现类。FutureTask有个done的方法,当任务跑完后这个方法将被调用,ListenableFutureTask则是重写了该方法,当执行完触发监听任务。 ListeningExecutorService.submit()返回的也是ListenableFutureTask对象
- 如果不需要通过跑任务来获得结果,那么可以自已继承AbstractFuture<V>或SettableFuture去重写set方法,注意其没有runnable的实现代码,提交不了线程池
- 当你原来代码用的是Future类,你可以使用JdkFutureAdapters.listenInPoolThread(Future)来转化,不过这个方式的代价比较大。最好不用这个方式
添加回调函数的其法
- ListenableFuture.addListener(Runnable, Executor) 当执行完成后调其他的线程池来跑回调方法
- Futures.addCallback(ListenableFuture<V>, FutureCallback<V>) 当执行完成后直接在当前线程跑回调方法, FutureCallback提供了onSuccess(V)当任务跑成功后被触发,和onFailure(Throwable) 当任务抛出异常时被触发
- Futures.addCallback(ListenableFuture<V>, FutureCallback<V>, Executor) 当执行完成后调其他的线程池来跑回调方法
Futures常用方法
Method | Description | See also |
transformAsync(ListenableFuture, AsyncFunction<A, B>, Executor)* | 异步的将ListenableFuture的结果使用AsyncFunction转化成另一个我们想要的其他格式的结果,该方法返回一个新的ListenableFuture实例 | transformAsync(ListenableFuture, AsyncFunction<A, B>) |
transform(ListenableFuture, Function<A, B>, Executor) | 同步的将ListenableFuture的结果使用AsyncFunction转化成另一个我们想要的其他格式的结果,该方法返回一个新的ListenableFuture实例 | transform(ListenableFuture, Function<A, B>) |
allAsList(Iterable<ListenableFuture<V>>) | 返回一个新的ListenableFuture,其获得的值是一个List, List是通过提供的多个ListenableFuture返回的结果。如果任何一个ListenableFuture失败或取消,这个方法将执行失败或取消(Returns a ListenableFuturewhose value is a list containing the values of each of the input futures, in order. If any of the input futures fails or is cancelled, this future fails or is cancelled.) | allAsList(ListenableFuture<V>...) |
successfulAsList(Iterable<ListenableFuture<V>>) | 返回一个新的ListenableFuture,其获得的值是一个List, List是通过提供的多个ListenableFuture返回的结果。如果某一ListenableFuture失败或取消,这个ListenableFuture将返回null(Returns a ListenableFuturewhose value is a list containing the values of each of the successful input futures, in order. The values corresponding to failed or cancelled futures are replaced with null.) | successfulAsList(ListenableFuture<V>...) |
ListenableFuture<RowKey> rowKeyFuture = indexService.lookUp(query);
AsyncFunction<RowKey, QueryResult> queryFunction =
new AsyncFunction<RowKey, QueryResult>() {
public ListenableFuture<QueryResult> apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture<QueryResult> queryFuture =
Futures.transformAsync(rowKeyFuture, queryFunction, queryExecutor);
CheckedFuture
Guava also provides a CheckedFuture<V, X extends Exception> interface. A CheckedFuture is a ListenableFuture that includes versions of the get methods that can throw a checked exception. This makes it easier to create a future that executes logic which can throw an exception. To convert a ListenableFuture to a CheckedFuture, use Futures.makeChecked(ListenableFuture<V>, Function<Exception, X>).