從零開始學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

相關文章
相關標籤/搜索