Netty的深入浅出--42.ChannelFuture的源码解析

上一章我们对比了concurrent包下的Future和netty包下的Future,现在我们继续回到主题,接着往下分析ChannelFuture

ChannelFuture继承了netty下的Future,而且很多方法都是重写了父类的。

ChannelFuture是异步I/0的一个结果

所有的I/O操作都是异步 ,它意味着这些调用将会立刻返回,这样的话并不能保证返回的I/O操作是已经完成的。

并且会返回一个返回一个I/O操作的状态结果信息的实例

ChannelFuture两种状态:完成状态和未完成状态

当一个I/O操作开始的时候,就会创建一个新的future。

 

新的I/O操作是一种初始化未完成的状态,它既不是成功的、失败的也不是取消的。而是一种未完成状态。

 

如果I/O操作是完成finish状态,它要么是成功执行了,要么是失败,要么就是取消了,该future会被标记这一些指定的信息,例如返回的失败原因。

 

总结一点:不管是失败还是取消对于Future来说都是属于完成的状态 。

提供了各种各样的方法让你能去检测是否I/O操作依据完成,或者等待完成,或者接收I/O操作的返回信息。

它允许你去增加ChannelFutureListenner,以至于你能够在I/O操作完成后,接收到通知

 

 建议我们不要使用await方法,建议我们使用addListener

之前分析过await方法不管有没有出现异常都不返回任何信息

 addListener是一个非阻塞的方法。它很简单的添加一个指定的ChannelFutureListener放入到ChannelFuture中。

相反,await方法是一个阻塞式的方法。被调用的时候,调用线程是被阻塞的直到操作完成为止。

 

channelHandler内部不能调用await,而await方法是阻塞的,这会使得channelHandler一直处于不能执行的阻塞状态,最终导致死锁dead lock。比方说:你等着你喜欢的女生来向你表白,而你喜欢的那个女生一直等着你向她表白。这种情况下两个人都一直处于一种等待对方的状态,变成了一个死循环。

 

 不要将等待超时,和I/O超时混淆

await指定的那些超时和I/O超时是没任何关系的

当I/O 操作超时的时候,他会以一种失败的完成方式返回

官方 提供了两个正反例子:

第一个反例:如果连接超时,但是我们在等待那里配置了超时时间,这里将会报I/O连接异常;

第二个正例:如果连接超时,但是我们在连接那里配置了等待超时时间,这样将会报I/O连接异常;

总结来说:channelFuture主要是对Future启动起到一个监听的作用。

猜你喜欢

转载自blog.csdn.net/qq_37909508/article/details/91274976