netty版本
- netty版本:
io.netty:netty-all:4.1.33.Final
Future/Promise异步模型
简介
- 在并发编程中,我们通常会用到一组非阻塞的模型:
Promise
,Future
和Callback
。其中的Future
表示一个可能还没有实际完成的异步任务的结果,针对这个结果可以添加Callback
以便在任务执行成功或失败后做出对应的操作,而Promise
交由任务执行者,任务执行者通过Promise
可以标记任务完成或者失败。 可以说这一套模型是很多异步非阻塞架构的基础。Netty 4中正提供了这种Future/Promise
异步模型。 - Netty的网络操作都是异步的,在源码上大量使用了
Future/Promise
模型,在Netty里面也是这样定义的:Future
接口定义了isSuccess()
,isCancellable()
,cause()
,这些判断异步执行状态的方法。(只读)Promise
接口在extends Future
的基础上增加了setSuccess()
,setFailure()
这些方法(可写)。即Promise
是可写的Future
。
Future
接口就是用来封装异步操作的执行状态的,在执行异步操作时,可以立马返回一个Future
,Future
可以sync
来等待执行结果,如果有些操作要等到Future
代表的异步操作完了才能执行,可以通过future.addListener()
的方式来在之前的异步操作完成的时候执行新的操作。- 外界看到的是
Future
,内部其实是Promise
,异步的时候一般是初始线程代码里封装一个Runnable,创建一个Promise
, 把Runnable放到其他线程池去执行,执行的时候把Promise
对象传进去(通过final关键字),在run()方法里结束时去改变Promise
的状态或设置结果的值。初始线程在设置异步操作时可以立马返回Future
(其实是Promise
),可以根据情况选择future.sync()
来同步等待结果或者future.addListener()
来设置异步操作。
Future
-
java.util.concurrent.Future
是Java提供的接口,表示异步执行的状态。- get():判断任务是否执行完成,如果完成就返回结果,否则阻塞线程,直到任务完成
- isDone():判断当前的异步操作是否完成,如果完成,无论成功与否,都返回true,否则返回false
- cancel: 尝试取消异步操作,结果是未知的,如果操作已经完成,或者发生其他未知的原因拒绝取消,取消操作将会失败
public V get() throws InterruptedException, ExecutionException { int s = state; if (s <= COMPLETING) s = awaitDone(false, 0L); return report(s); }
ChannelFuture
-
Netty中所有的I/O操作都是异步执行的,例如你连接一个主机默认是异步完成的;写入/发送消息同样也是异步。也就是说操作不会直接执行,而是会等一会执行,因为你不知道返回的操作结果是成功还是失败,但是需要有检查是否成功的方法或者是注册监听来通知;Netty使用
io.netty.util.concurrent.Future
(继承JDK的Future
)和ChannelFuture
来达到这种目的。Future
注册一个监听,当操作成功或失败时会通知。ChannelFuture
封装的是一个操作的相关信息,操作被执行时会立刻返回ChannelFuture
。 -
ChannelFuture
接口扩展了Netty的o.netty.util.concurrent.Future
接口,表示一种没有返回值的异步调用,同时关联了Channel
,跟一个Channel
绑定(因此命名为ChannelFuture
)。ChannelFuture
接口其addListener()
方法注册一个ChannelFutureListener
,以便在某个操作完成时(无论是否成功)得到通知public interface ChannelFuture extends Future<Void> { Channel channel(); @Override ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener); @Override ChannelFuture addListeners(GenericFutureListener<? extends Future<? super Void>>... listeners); @Override ChannelFuture removeListener(GenericFutureListener<? extends Future<? super Void>> listener); @Override ChannelFuture removeListeners(GenericFutureListener<? extends Future<? super Void>>... listeners); @Override ChannelFuture sync() throws InterruptedException;