JAVA异步实现(2):guava-ListenableFuture
ListenableFuture的线程运行状态分析见ListenableFuture的线程运行状态分析
在JDK1.8之前,java官方一直没有提供比Future更好的异步工具(Future相关在前一篇博客中有介绍),为此google的guava库中提供了ListenableFuture作为Future的工具,在JDK1.8中增加了CompletableFuture作为对Future的补充,见下一篇博客。
本文的maven依赖如下:
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
ListenableFuture
顾名思义,ListenableFuture的意思就是可以被Listen(监听)的Future,下面是ListenableFuture的定义:
public interface ListenableFuture<V> extends Future<V> {
/*
* @param listener the listener to run when the computation is complete
* @param executor the executor to run the listener in
* @throws RejectedExecutionException if we tried to execute the listener immediately but the
* executor rejected it.
*/
void addListener(Runnable var1, Executor var2);
}
可以看到,ListenableFuture继承自Future,比Future增减了一个addListener()方法,该方法的参数如源码中的注释:当ListenableFuture的计算结束(Future#isDone())以后自动调用Executor去执行Runnable中的任务。
【需要特别注意的是,根据Future源码中的注释,Future获得返回值、出现异常、被取消isDone()都返回true,所以只有Runnable或者Callable还在执行过程中的时候才会返回false】
/**
* Returns {@code true} if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* {@code true}.
*
* @return {@code true} if this task completed
*/
boolean isDone();
下面是demo1。
@Test
public void addListenerTest() {
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(5);
//ListenableFuture必须被ListeningExecutorService执行才会返回,MoreExecutors提供了很多有用的方法
ListeningExecutorService es = MoreExecutors.listeningDecorator(executorService);
//提交,callable返回1,callable中的任务不会立即执行,等待添加了回调之后才会执行
ListenableFuture<Integer> listenableFuture = es.submit(() -> 1);
//注册监听,如果callable正常返回则打印,这里futrue中的任务才会被执行
listenableFuture.addListener(() -> System.out.println("computation is end"), executorService);
}
下面根据源码看看MoreExecutors#listeningDecorator中创建ListenableFuture的过程:
public static ListeningExecutorService listeningDecorator(ExecutorService delegate) {
return (delegate instanceof ListeningExecutorService)
? (ListeningExecutorService) delegate
: (delegate instanceof ScheduledExecutorService)
? new ScheduledListeningDecorator((ScheduledExecutorService) delegate)
: new ListeningDecorator(delegate);
}
//可以看根据传入的ExecutorService的具体实现返回了不同的ListeningExecutorService 接口的实现,在上面的代码中是最后一种,也就是创建了一个ListeningDecorator类
private static class ListeningDecorator extends AbstractListeningExecutorService {
private final ExecutorService delegate;
ListeningDecorator(ExecutorService delegate) {
this.delegate = checkNotNull(delegate)