Channel,EventLoop,ChannelPipeline,EventExecutor和ChannelHandler之間的關係
每一個channel持有一個eventLoop, channel.unsafe的方法會在這個eventLoop中執行。那麼問題來了,使用add方法向channelPiple中添加一個channelHandler,這個handler的方法在哪裏執行呢?下面以addLast爲例看看添加方法。
ChannelPipeline addLast(ChannelHandler... handlers)
ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers)
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler)
channelPiple負責爲每一個新添加的handler分配一個eventExecutor。若是你調用了帶grop參數的方法添加handler ,channelPiple會從group中取出一個eventExecutor分配給這個handler, 這時handler中的回調方法會在這個eventExecutor線程中執行,不然channelPiple會把channel的eventLoop當成eventExecutor分配給這個handler,這時這個handler的回調方法會在eventLoop的線程中執行。這個二者有什麼不一樣呢?若是沒你沒有給handler指定group,它將會和channel的I/O操做共享線程資源,它能獲得多少線程資源取決於eventLoop的ioRatio屬性的設置,執行時間過長的handler的回調方法會影響I/O操做。若是指定了group,handler的回調方法和channel的I/O操做將會被隔離到不一樣的線程中。在高併發狀況下,強烈建議爲不一樣功能的handler指定不一樣的group。
每一個channel實例在建立的時候,它本身負責建立一個channelPiple實例。隨後這個channel會被註冊到一個eventLoop中,eventLoop負責處理channel上觸發的I/O事件,把I/O事件轉換成對channel.unsafe方法的調用。unsafe負責作實際的I/O操做,根據須要調用channelPiple觸發事件。channelPiple依次調用合適的handler處理事件。這裏的"依次」和「合適」的含義是:
- 若是是inbound事件,會從頭至尾按順序調用雙向鏈表上的ChannelInboundHandler類型的handler。
- 若是是outbound事件,會從尾到頭按順序調用雙向鏈表上的ChannelOutboundHandler類型的handler。
piplePile確保一個handler調用始終在一個惟一的eventExecutor中,這個eventExecutor多是channel的eventLoop,也多是從用戶指定的eventExecutorGroup中分配到的一個executor。