从零开始学netty——为什么重写方法不同

从零开始学netty——第一个netty程序
从零开始学netty——认识decoderapi

相信你们看了decoder部分的时候确定有点怪异,尤为是发现重写的方法是channelRead0。方法上还带了数字,彻底不如channelRead好理解,下面的内容就是解答这个疑惑的。数组

继承类的差别

第一个程序继承的是ChannelInboundHandlerAdapter类,第二个程序是继承的是SimpleChannelInboundHandler,SimpleChannelInboundHandler是有泛型参数的。能够指定一个具体的类型参数,经过decoder配合使用,很是方便。ChannelInboundHandlerAdapter则是直接操做byte数组的。异步

类的关系

ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler
SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter

上图就是两个类的声明,SimpleChannelInboundHandler是继承ChannelInboundHandlerAdapter的。也就是说SimpleChannelInboundHandler也拥有ChannelInboundHandlerAdapter的方法。jvm

channelRead的重写

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        boolean release = true;
        try {
            if (acceptInboundMessage(msg)) {//类型匹配
                I imsg = (I) msg;
                channelRead0(ctx, imsg);
            } else {
                release = false;
                ctx.fireChannelRead(msg);
            }
        } finally {
            if (autoRelease && release) {
                ReferenceCountUtil.release(msg);//释放引用
            }
        }
    }

SimpleChannelInboundHandler的channelRead相比SimpleChannelInboundHandler而言,主要作了类型匹配以及用完以后释放指向保存该消息的 ByteBuf 的内存引用。学习

ChannelInboundHandlerAdapter 的好处

相比之下,ChannelInboundHandlerAdapter 好像一无可取,毕竟他要本身处理资源的释放,例如以下的调用.net

buf.release();

若是说channelRead都是同步操做的话,SimpleChannelInboundHandler是不错的选择,若是操做是异步的话,那他的逻辑就有点麻烦了,例如你把数据交给另外的线程处理了,还没处理就会释放了 。这里必须说明一个问题,他的回收和jvm的垃圾回收还不彻底是一回事。netty是本身作了引用计数的操做。线程

buf.refCnt();

经过上面的api就能够获取到计数的个数。具体的引用计数的部分,不知道也不影响netty的学习,这个点后面具体再说。ChannelInboundHandlerAdapter 处理自由的优势也就提现出来了,能够更好的处理更多的特定场景。netty

小总结

SimpleChannelInboundHandler的好处是能够处理不一样的类型对象,而且能够作释放。ChannelInboundHandlerAdapter 的好处则是更自由,在异步的场景下更适合。code

相关文章
相关标签/搜索