攜手共進——《Netty IN ACTION》中文版《Netty實戰》答疑解惑
引子
所謂一千個人的眼中,就會有一千個哈姆雷特,每位讀者對於一本書中的意境的理解都是不一樣的,當然這也包括技術類書籍。可是對於技術書籍來說,最重要的就是準確性,這種準確性是要求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
。
如果大家還有什麼不明白,可以在下麵留言、
最後更新:2017-06-07 15:31:51