前面文章“多线程之Runnable,Callable,Future,FutureTask”中介绍了多线程Future的相关内容,传统JDK中的Future表示一个异步计算任务,当任务完成时可以得到计算结果。Future是运行中的多线程的一个引用句柄,确保在服务执行返回一个Result。如果我们希望一旦计算完成就拿到结果展示给用户或者做另外的计算,就必须使用另一个线程不断的查询计算状态。这样做,代码复杂,而且效率低下。使用ListenableFuture Guava帮我们检测Future是否完成了,如果完成就自动调用回调函数,这样可以减少并发程序的复杂度。ListenableFuture可以允许你注册回调方法(callbacks),在运算完成的时候进行调用, 。这样简单的改进,使得可以明显的支持更多的操作,这样的功能在JDK中的concurrent中的Future是不支持的。
ListenableFuture:
public interface ListenableFuture<V> extends Future<V> {
void addListener(Runnable listener, Executor executor);
}
不过大部分使用addCallback(ListenableFuture<V> future,FutureCallback<? super V> callback))来添加回调。
其中FutureCallback中有两个方法:
public interface FutureCallback<V> {
/**
* Invoked with the result of the {@code Future} computation when it is
* successful.
*/
void onSuccess(V result);
/**
* Invoked when a {@code Future} computation fails or is canceled.
*
* <p>If the future's {@link Future#get() get} method throws an {@link
* ExecutionException}, then the cause is passed to this method. Any other
* thrown object is passed unaltered.
*/
void onFailure(Throwable t);
}
onSuccess(V): 在Future成功的时候执行,根据Future结果来判断。
onFailure(Throwable): 在Future失败的时候执行,根据Future结果来判断。
对应JDK中的 ExecutorService.submit(Callable) 提交多线程异步运算的方式,Guava 提供了ListeningExecutorService 接口, 该接口返回 ListenableFuture 而相应的ExecutorService 返回普通的 Future。ListeningExecutorService可以通过MoreExecutors.listeningDecorator(ExecutorService)来生成。
使用方法如下:
public class ListableFutureTest {
private ExecutorService executor = Executors.newFixedThreadPool(1);
private ListeningExecutorService service = MoreExecutors.listeningDecorator(executor);
public static void main(String[] args){
ListableFutureTest test = new ListableFutureTest();
ListenableFuture<Student> future = test.service.submit(new Callable<Student>() {
@Override
public Student call() throws Exception {
Thread.sleep(1000*5);
return new Student("张三", "男");
}
});
Futures.addCallback(future, new FutureCallback<Student>() {
@Override
public void onSuccess(Student result) {
System.out.println("执行结果"+result);
}
@Override
public void onFailure(Throwable t) {
System.out.println("error=============");
}
});
System.out.println("abcdd");
}
}