1 Further模式的原理
在多线程编程中,一个很重要的问题就是同步和阻塞,按照一般的处理流程,当发出一个请求之后,需要一直等待直到这个请求返回结果之后,调用者才能继续做其他事情,这样就造成了阻塞,降低了效率。而采用Future模型,则可以无需等待结果而直接返回,继续执行其他操作,而当调用者需要去获取结果的时候,才会去真正阻塞,直到拿到结果或者超时;或者是通过一种机制能够在结果获取之后通知到被调用者。其具体执行过程如下图所示:
2 netty中的Future模式实现
Netty中的Future实现叫做ChannelFuture,与异步I/O操作相关。由以上的分析,我们知道,Future模式可以解决异步I/O调用过程中调用者获取异步操作结果的问题。但是从其实现上来看,通过Future的阻塞get()方法获取结果的方式不够灵活,也会影响性能,因为如果设置了超时时间,而我们实际上并无法事先知道调用的耗时情况,导致请求超时返回或者等待过长的时间,而如果不设置超时时间,则会造成线程长时间被阻塞。ChannelFuture为了解决这个问题进行了专门的设计,可以通过设置监听器的方式获取结果。
在netty中,ChannelFuture提供了一系列API,用于获取操作结果、添加事件监听器、取消I/O操作、同步等待等。而Netty强烈建议采用添加监听器的方式获取I/O操作结果,并进行后续的结果处理。
ChannelFuture可以同时增加一个或者多个GenericFutureListener,也可以用remove方法删除GenericFutureListener。当一个I/O操作完成之后,I/O线程会回调ChannelFuture中GenericFutureListener的operationComplete方法,并把ChannelFuture对象当做方法的入参。从中我们就可以拿到异步调用的结果。如果用户还需要做上下文相关的操作,也需要将上下信息保存到对应的ChannelFuture中。
结论:Future模式是一个很好地实现异步非阻塞调用的机制,它通过事件监听回调的方式很巧妙地实现了异步调用中调用者获取调用结果的方法。