Netty的EventLoop和EventLoopGroup

EventLoopGroup : 事件循環組

EventLoop:事件循環

  1. 1個EventLoopGroup中包含1個或多個EventLoop
  2. 1個EventLoop在它的整個生命週期當中只會與唯一一個Thread進行綁定
  3. 所有由EventLoop所處理的各種I/O事件都將在它關聯的那個Thread上進行處理。
  4. 一個Channel在它的整個生命週期中只會註冊在一個EventLoop上。
  5. 一個EventLoop在運行過程當中,會被分配給一個或多個Channel。

總結:絕對不要在handler中做任何耗時的工作,一旦發生就會將EventLoop中的線程給卡在耗時的事件上,這樣其他許多channel的I/O事件都會等待,

解決辦法:在handler中啓動一個線程池

 

PS:當你去執行Channel上的任何一個操作時,netty一定會首先去判斷執行這個操作的線程是否就是Channel所對應的EventLoop所包含的線程,如果是則直接執行,否則netty以一個任務的形式提交給EventLoop,最終執行這個任務的線程還是EventLoop中的線程,通過這樣精巧的設計,netty在整個channel的操作上消除了所有的需要同步的地方。

 

重要結論:在Netty中,channel的實現一定是線程安全的,基於此,我們可以存儲一個channel的引用,並且在需要向遠程端點發送數據時,通過這個引用來調用channel相應的方法;即便當時有很多線程都在使用它也不會出現多線程問題;而且,消息一定會按照順序發送出去。

 

重要結論2:我們在業務開發中,不要將長時間執行的耗時任務放入到EventLoop的執行隊列中,因爲它將會一直阻塞該線程對應的所有channel上的其他執行任務,如果我們需要執行阻塞調用或是耗時的操作(開發中常見),那麼我們就需要使用一個專門的EventExecutor(業務線程池)。

 

:EventExecutor的兩種實現方式

1. 在ChannelHandler的回調方法中,使用自己定義的業務線程池,這樣就可以實現異步調用

2.藉助netty提供的向ChannelPipeline添加ChannelHandler時調用addLast方法來傳遞EventExecutor.

 

說明:默認情況下(調用addLast(handler)),channelHandler中的回調發放都是由I/O線程所執行,如果調用了ChannelPipeline addLast(EventExecutorGroup group,ChannelHandler .. handlers)方法,那麼ChannelHandler中的回調方法就是由參數中的group線程組來執行的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章