EventLoop 介面
Netty 是基于 Java NIO 的,因此 Channel 也有其生命周期,處理一個連接在其生命周期內發生的事件是所有網路框架的基本功能,通常來說,我們使用一個執行緒來處理一個連接,該連接的生命周期的某一事件就緒,則會呼叫對應的事件處理邏輯
在 Netty 中,一個 EventLoop 負責處理一個 Channel 的生命周期事件,在代碼設計上,EventLoop 間接實作了 JUC 中的 ExecutorService 和 ScheduleExecutorService 兩個介面,因此其具有了執行緒池的特性,一個 EventLoop 將由一個永遠不會改變的 Thread 驅動,EventLoop 由一個 Selector 和 TaskQueue 組成,Selector 會選擇 Channel 生命周期中某一事件,并由 EventLoop 所在的執行緒選擇對應的 ChannelHandler 進行處理,除此之外,用戶還可以手動提交任務給 EventLoop,以立即執行或調度執行
任務調度
有時候,你希望在 Channel 中調度一個任務以立即執行、稍后執行或者周期性執行,然而,這些任務有可能會造成長時間的阻塞,如果寫在 ChannelHandler 里面,則有可能會阻塞整個執行鏈,因此,我們可以把這些任務提交給 EventLoop,EventLoop 會把這些任務放入 TaskQueue 中,等待創建執行緒去執行,這個程序是異步非阻塞的,不會影響到主執行鏈
Channel ch = ...;
ScheduleFuture<?> future = ch.eventLoop().schedule(
// 創建一個 Runnable 以供調度稍后執行
new Runnable() {
@Override
public void run() {
// 要執行的代碼
System.out.println("60 second later");
}
}, 60, TimeUnit.SECONDS);
由此我們知道,EventLoop 所在執行緒負責一個 Channel 的整個生命周期內的所有事件,有時候,我們還會在別的執行緒去獲取一個 Channel,并向該 Channel 對應的 EventLoop 提交任務,這種非對應 Channel 所提交過來的任務,EventLoop 會把它放入任務佇列中,等待下次執行

EventLoop 的執行緒分配
服務于 Channel 的 EventLoop 包含在 EventLoopGroup 中,根據不同的傳輸實作,EventLoop 的創建和分配方式也不同
1. 異步傳輸
異步傳輸實作只使用了少量的 EventLoop,一個 EventLoop 可能會被多個 Channel 所共享,通過盡可能少的執行緒來支撐大量的 Channel,而不是每個 Channel 分配一個 Thread

需要注意的是,一個 EventLoop 被用于支撐多個 Channel,那么對于所有相關聯的 Channel 來說,ThreadLocal 是一樣的,這使得它對于實作狀態追蹤等功能來說是個糟糕的選擇
2. 阻塞傳輸
每一個 Channel 都將分配給一個 EventLoop,每個 Channel 的 IO 事件都將只會被一個 Thread 處理

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/288196.html
標籤:其他
上一篇:PHP中PDO關閉連接的問題
下一篇:使用系統引數表,提升系統的靈活性
