netty框架中的ChannelFuture 详解

netty是event-driven模型,channel的I/O操作都是异步执行,在构建项目的时候,我们不可避免的需要channel的I/O操作具有sequential logic。如在发送数据之后,希望在成功的时候记录一下,失败记录到数据库。或者在聊天的项目中用于防止重复登录场景,发现同一个id建立两次连接,需要先进行对先前的id资源回收,再让后一个id进行登录。这个需要就需要用到ChannelFuture。

ChannelFutrue的UML类图:

netty ChannelFuture - zhanghua.1199 - 郁,加没

ChannelFuture可以增加ChannelFutureListener对象(可以增加多个,当操作完成,会顺序调用listener的operationComplete方法),
netty ChannelFuture - zhanghua.1199 - 郁,加没

 里面的CLOSE和CLOSE_ON_FAILURE实现好的两个listener内部类,里面的代码是:

 /**      * A {@link ChannelFutureListener} that closes the {@link Channel} which is      * associated with the specified {@link ChannelFuture}.      */     ChannelFutureListener CLOSE = new ChannelFutureListener() {         public void operationComplete(ChannelFuture future) {             future.getChannel().close();         }     };

    /**      * A {@link ChannelFutureListener} that closes the {@link Channel} when the      * operation ended up with a failure or cancellation rather than a success.      */     ChannelFutureListener CLOSE_ON_FAILURE = new ChannelFutureListener() {         public void operationComplete(ChannelFuture future) {             if (!future.isSuccess()) {                 future.getChannel().close();             }         }     };


这里说明一点:Channel的close方法返回的ChannelFuture永远都是同一个future实例,所以你可以在channel一打开的情况下,就注册一些关闭的流程。
执行channel.close()方法有两个地方会收到通知,一个是handler,一个是future。handler会在future之前收到channel close的通知
官方的详细介绍:
     在netty中所有的I/O操作都是异步,这意味着netty提供的I/O方法调用都将立即返回,会返回一个ChannelFuture对象的实像,它将会给你一些信息,关于I/O执行状态的结果,但此时不能保证真正的I/O操作已经完成。

    ChannelFuture对象状态只有uncompleted和completed。当一个I/O操作开始时,一个ChannelFuture实例被创建(我知道的暂时除close方法),刚开始时,future对象的实例即不是succeeded,failed,cancelled。因为真正的I/O操作还没有完成。如果正的I/O操作已经完成,那么future的状态将是completed,无论结果是succeeded,failed,cancelled。

netty ChannelFuture - zhanghua.1199 - 郁,加没

各种方法都提供了让你检查I / O操作已经完成,等待完成,和检索结果的I / O操作,它还允许你添加ChannelFutureListeners,当I / O操作完成你可以异步收到通知。

推荐使用addListener(ChannelFutureListener)异步得到通知当一个I / O操作完成后,做任何后续任务,而不是通过调用await方法(降低吞吐量)。但如果你想要业务场景是必须先执行A,然后同步执行B(异步通知不合适的场景),使用await是比较方便的。但await有一个限制,调用await方法的线程不能是I/O 线程(work线程),否则会抛出一个异常,避免死锁。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值