本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/51758194
1、前言
在前两篇文章中简单阐述了Java Future 和Guava ListenableFuture及其相关的应用。我们发现Guava ListenableFuture提供了比Java Future更加强大的功能,而在Google Guava并发包中,某些情况下,Futures这个类起到了不可或缺的作用,而ListenableFuture实现非阻塞的原理是其提供了回调机制(机制),下面将阐述其中的回调机制的实现,主要对Futures的addCallback方法源码进行详细的剖析。
2、Guava Futures简介
Google Guava框架的 com.google.common.util.concurrent包是并发相关的包,它是对JDK自带concurrent包中Future和线程池相关类的扩展,从而衍生出一些新类,并提供了更为广泛的功能。在项目中常用的该包中类如下所示:
ListenableFuture:该接口扩展了Future接口,增加了addListener方法,该方法在给定的excutor上注册一个监听器,当计算完成时会马上调用该监听器。不能够确保监听器执行的顺序,但可以在计算完成时确保马上被调用。
FutureCallback:该接口提供了OnSuccess和onFailure方法。获取异步计算的结果并回调。
MoreExecutors:该类是final类型的工具类,提供了很多静态方法。例如listeningDecorator方法初始化ListeningExecutorService方法,使用此实例submit方法即可初始化ListenableFuture对象。
ListenableFutureTask:该类是一个适配器,可以将其它Future适配成ListenableFuture。
ListeningExecutorService:该类是对ExecutorService的扩展,重写了ExecutorService类中的submit方法,并返回ListenableFuture对象。
JdkFutureAdapters:该类扩展了FutureTask类并实现ListenableFuture接口,增加了addListener方法。
Futures:该类提供和很多实用的静态方法以供使用。
3、Futures.addCallback方法源码剖析
下面将模拟异步发送请求,并对请求结果进行(回调)监听。这里使用Spring框架提供的AsyncRestTemplate,来发送http请求,并获取一个org.springframework.util.concurrent.ListenableFuture对象,此时的对象是spring框架中的ListenableFuture对象。由于org.springframework.util.concurrent包中只提供了最基本的监听功能,没有其它额外功能,这里将其转化成Guava中的ListenableFuture,用到了JdkFutureAdapters这个适配器类。(以下源码来自guava-18.0.jar)
AsyncRestTemplate tp = new AsyncRestTemplate();
org.springframework.util.concurrent.ListenableFuture<ResponseEntity<Object>> response = tp
.getForEntity("http://blog.csdn.net/pistolove", Object.class);
ListenableFuture<ResponseEntity<Object>> listenInPoolThread = JdkFutureAdapters.listenInPoolThread(response);
Futures.addCallback(listenInPoolThread, new FutureCallback<Object>() {
@Override
public void onSuccess(Object result) {
System.err.println(result.getClass());
System.err.printf("success", result);
}
@Override
public void onFailure(Throwable t) {
System.out.printf("failure");
}
});
Futures的addCallback方法通过传入ListenableFuture和FutureCallback(一般情况FutureCallback实现为内部类)来实现回调机制。
//com.google.common.util.concurrent.Futures
public static <V> void addCallback(ListenableFuture<V> future,
FutureCallback<? super V> callback) {
addCallback(future, callback, directExecutor());
}
在addCallback方法中,我们发现多了一个 directExecutor()方法,这里的 directExecutor()方法返回的是一个枚举类型的线程池,这样做的目的是提高性能