MoreExecutors
directExecutor
执行 callback 的线程池这里指定为 MoreExecutors#directExecutor,那么这里执行打印 result 的线程是主线程
在 MoreExecutors#directExecutor 中,可以看到定义是这样的:
以及
MoreExecutors#directExecutor 其实是一个假的线程池,表示直接执行。
再看下面这个例子:
那么这里清晰了:
如果 future 已经完成,那么
MoreExecutor#directExecutor表示当前线程;如果 future 未完成,那么
MoreExecutor#directExecutor就是未来完成 future 的线程。
因此其实具体执行回调的线程某种程度上是不确定的
ListenableFuture
引言
jdk原生的future已经提供了异步操作,但是不能直接回调。guava对future进行了增强,核心接口就是ListenableFuture。JDK8从guava中吸收了精华新增的类CompletableFuture,也可以直接看这个类的学习。
JUC 的 Future 接口提供了一种异步获取任务执行结果的机制,表示一个异步计算的结果。
Executor 实际返回的是实现类 FutureTask,它同时实现了 Runnable 接口,因此可以手动创建异步任务。
而 Guava 提供的 ListenableFuture 更进一步,允许注册回调,在任务完成后自动执行,实际也是使用它的实现类 ListenableFutureTask。
回调源码剖析
先看下ListenableFuture接口定义:
可以看到,这个接口在Future接口的基础上增加了addListener方法,允许我们注册回调函数。当然,在编程时可能不会直接使用这个接口,因为这个接口只能传Runnable实例。
addListener方法
这里其实就是在添加listener的方法中首先检查Future是否已经完成:
如果Future已经完成,那么就没有必要添加新的监听器,直接executeListener。
如果future没有完成,那么会新建一个Listener节点,并插入到链表头部(Listener就是一个链表)
如果已经完成,会直接执行executeListner 方法
那么如果没有完成呢,在listener链表中的什么时候会执行?看后续的回调函数的触发内容
addCallback方法
Futures类还提供了另一个回调方法:addCallback方法
这里调用了ListenableFuture接口的addListener方法,传入了一个CallbackListener实例。而这个实例由需要传入future和一个Callback实例,所以这个回调是可以拿到返回值的。本质上是guava基于Runnable封了一个回调接口。
看下这个CallbackListener接口:
那么这个回调函数什么时候会执行?看后续的回调函数的触发内容
回调函数的触发
那么这些回调方法什么时候会触发呢?
那哪些方法会来调用这个complete方法呢?

Service
Guava 的 Service 框架是一个用于管理服务生命周期的轻量级框架,可以帮助我们把异步操作封装成一个Service服务。让这个服务有了运行状态(也可以理解成生命周期),这样可以实时了解当前服务的运行状态。同时还可以添加监听器来监听服务运行状态之间的变化。
Guava里面的服务有五种状态,如下所示:
Service.State.NEW: 服务创建状态
Service.State.STARTING: 服务启动中
Service.State.RUNNING:服务启动完成,正在运行中
Service.State.STOPPING: 服务停止中
Service.State.TERMINATED: 服务停止完成,结束
所有的服务都需要实现Service接口,里面包括了服务需要实现的一些基本方法,以下是Service接口:
那应该怎么来使用Service,需要实现的异步逻辑包装成服务呢.Guava里面已经给提供了三个基础实现类:
AbstractService
AbstractExecutionThreadService
AbstractScheduledService
AbstractExecutionThreadService
AbstractExecutionThreadService可以把一个具体的异步操作封装成Service服务。说白了就是把之前在线程的实现逻辑封装成服务,把之前线程的具体实现逻辑搬到AbstractExecutionThreadService的实现方法run()方法去执行。
常用方法介绍
首先AbstractExecutionThreadService实现了Service,Service的方法在AbstractExecutionThreadService里面都有,AbstractExecutionThreadService新加了一些方法。如下所示:
AbstractExecutionThreadService类里面最重要的就是run()方法了,这个方法是服务需要具体实现的方法,服务需要处理的具体逻辑在这个方法里面做。
具体使用
AbstractScheduledService
AbstractScheduledService可以把周期性的任务封装成一个服务。线程池也有一个周期性的线程池么,两者是一一对应的.
常用方法介绍
AbstractScheduledService也是一个服务所以Service里面的方法AbstractScheduledService也都有,同时,AbstractScheduledService也新增了一些其它方法
具体使用
自定义一个类继承AbstractScheduledService,实现一个非常简单的周期性任务.
ServiceManager
ServiceManager是用来管理多个服务的,让对多个服务的操作变的更加方便,比如可以同时去启动多个服务,同时去停止多个服务等等。