携手共进——《Netty IN ACTION》中文版《Netty实战》答疑解惑

引子

所谓一千个人的眼中,就会有一千个哈姆雷特,每位读者对于一本书中的意境的理解都是不一样的,当然这也包括技术类书籍。可是对于技术书籍来说,最重要的就是准确性,这种准确性是要求100%的,不能说“千人千面”。作为书籍的作者和译者,自然在表达的时候可能有所纰漏,不能做到面面俱到,所以也就有了这篇小文,用来收集以及解答译者收到的读者的一些反馈和疑问,希望能够帮助到大家。

共进

  • 书中说的每一个Channel都具有唯一的id是什么意思呢,如果返回相同的hashCode就会报错?

解惑:书中对于这一块儿的描述其实不是特别的详细,只是给出了结论,但是并没有给出为何。首先id的意思是identity,即唯一标识,类似于我们的身份证。那么为何Channel的唯一标识必须是唯一的呢?这是因为一个网络连接(这里不指面向连接、或者无连接的协议)总是由一个(SourceIP,SourcePORT,TargetIP,targetPORT )唯一确定的,这个四元组是不会重复的吧,这里排除(IP和端口)复用的情况。所以这就是为何设计成每个Channel的id都是唯一确定的。具体的可以查看io.netty.channel.AbstractChannel#compareTo的代码。那么有什么时候报错呢,如上面的代码,即调用compareTo的时候。一个很常见的场景便是通过调用ChannelGroupadd(Channel)方法,将一个Channel添加到ChannelGroup时,其中ChannelGroup的内部使用了由ConcurrentHasmMap实现的ConcurrentHashSet,说到这里,读者应该明白了吧,因为后面的逻辑,compareTo的调用已经是HashMap的逻辑了。

  • 书中说的当一个Channel被标记为@Shareable的时候才可以被同时添加到多个ChannelPipeline中,否则的话就会报错,这是为何呢?

解惑:书中并没有提到源码层面是如何实现的,实际上,在 Netty 目前基于 EventLoop 的线程模型中,Netty 是要求用户的ChannelHandler的实现必须要是线程安全的。这样,其便可以在不同的ChannelChannelPipeline中安全的共享。所以,设计上为了避免非线程安全的ChannelHandler被错误地共享,所以 Netty 要求你标注一个ChannelHandler@Shareable来指示它的线程安全性。在内部,每一个ChannelHandler都有一个isAdded字段,这个字段在ChannelPipelineadd/set*(ChannelHandler)被调用的时候将会读取。源码见:io.netty.channel.ChannelHandlerAdapter#addedio.netty.channel.DefaultChannelPipeline#checkMultiplicity

如果大家还有什么不明白,可以在下面留言、

上一篇:为什么lisp这么强大的语言用的人这么少


下一篇:《Netty IN ACTION》中文版《Netty实战》翻译手记——不负好时光