引子
所谓一千个人的眼中,就会有一千个哈姆雷特,每位读者对于一本书中的意境的理解都是不一样的,当然这也包括技术类书籍。可是对于技术书籍来说,最重要的就是准确性,这种准确性是要求100%的,不能说“千人千面”。作为书籍的作者和译者,自然在表达的时候可能有所纰漏,不能做到面面俱到,所以也就有了这篇小文,用来收集以及解答译者收到的读者的一些反馈和疑问,希望能够帮助到大家。
共进
- 书中说的每一个
Channel
都具有唯一的id是什么意思呢,如果返回相同的hashCode
就会报错?
解惑:书中对于这一块儿的描述其实不是特别的详细,只是给出了结论,但是并没有给出为何。首先id
的意思是identity
,即唯一标识,类似于我们的身份证。那么为何Channel
的唯一标识必须是唯一的呢?这是因为一个网络连接(这里不指面向连接、或者无连接的协议)总是由一个(SourceIP,SourcePORT,TargetIP,targetPORT )
唯一确定的,这个四元组是不会重复的吧,这里排除(IP和端口)复用的情况。所以这就是为何设计成每个Channel
的id都是唯一确定的。具体的可以查看io.netty.channel.AbstractChannel#compareTo
的代码。那么有什么时候报错呢,如上面的代码,即调用compareTo
的时候。一个很常见的场景便是通过调用ChannelGroup
的add(Channel)
方法,将一个Channel
添加到ChannelGroup
时,其中ChannelGroup
的内部使用了由ConcurrentHasmMap
实现的ConcurrentHashSet
,说到这里,读者应该明白了吧,因为后面的逻辑,compareTo
的调用已经是HashMap
的逻辑了。
- 书中说的当一个
Channel
被标记为@Shareable
的时候才可以被同时添加到多个ChannelPipeline
中,否则的话就会报错,这是为何呢?
解惑:书中并没有提到源码层面是如何实现的,实际上,在 Netty 目前基于 EventLoop
的线程模型中,Netty 是要求用户的ChannelHandler
的实现必须要是线程安全的。这样,其便可以在不同的Channel
的ChannelPipeline
中安全的共享。所以,设计上为了避免非线程安全的ChannelHandler
被错误地共享,所以 Netty 要求你标注一个ChannelHandler
为@Shareable
来指示它的线程安全性。在内部,每一个ChannelHandler
都有一个isAdded
字段,这个字段在ChannelPipeline
的add/set*(ChannelHandler)
被调用的时候将会读取。源码见:io.netty.channel.ChannelHandlerAdapter#added
和io.netty.channel.DefaultChannelPipeline#checkMultiplicity
。
如果大家还有什么不明白,可以在下面留言、