怎麼破解U盤加密狗

從EventLoop的繼承圖中可以看出,EventLoop繼承了jdk的Executor和ScheduleExecutorService等接口,熟悉線程池的朋友應該知道這兩個接口主要作用是用來提交任務和執行定時任務的。
而EventLoop的主要作用有兩個,一方面在內部維護了一個任務隊列,另一方面EventLoop持有一個多路複用選擇器Selector。EventLoop會不停的從任務隊列中獲取任務執行,同時也會關注Selector是否有可用的連接。如果有可用的連接,EventLoop也會處理這些連接。
protected void run() {
int selectCnt = 0;
for (; ; ) {
if (ioRatio == 100) {
try {
if (strategy > 0) {
//查看Selector的連接狀態
processSelectedKeys();
}
} finally {
//運行任務隊列的任務
ranTasks = runAllTasks();
}
} else if (strategy > 0) {
final long ioStartTime = System.nanoTime();
try {
processSelectedKeys();
} finally {
// Ensure we always run tasks.
final long ioTime = System.nanoTime() - ioStartTime;
ranTasks = runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
}
} else {
ranTasks = runAllTasks(0); // This will run the minimum number of tasks
}
}
}
複製代碼上述代碼是EventLoop的一個實現類NioEventLoop的run方法。爲了閱讀方便去掉了其他一些代碼。從上述代碼中可以看出,EventLoop在一個死循環中不停的關注任務隊列和Selector的連接情況。
EventLoopGroup
EventLoopGroup從名字也可以看出,這是一個EventLoop的集合。這個類的內部持有多個EventLoop,他的主要作用就是將收到的任務均勻的分配給內部持有的EventLoop。
Channel
Channel我們可以把他理解爲Netty對jdk的Socket的封裝,一個Channel內部會持有一個Socket。同時Channel內部還會持有一個ChannelPipeline對象。ChannelPipeline對象會把我們對Socket的處理邏輯串聯起來。
I/O Request
via {Channel} or
{ChannelHandlerContext}
|
±--------------------------------------------------±--------------+
| ChannelPipeline | |
| |/ |
| ±--------------------+ ±----------±---------+ |
| | Inbound Handler N | | Outbound Handler 1 | |
| ±---------±---------+ ±----------±---------+ |
| /|\ | |
| | |/ |
| ±---------±---------+ ±----------±---------+ |
| | Inbound Handler N-1 | | Outbound Handler 2 | |
| ±---------±---------+ ±----------±---------+ |
| /|\ . |
| . . |
| ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
| [ method call] [method call] |
| . . |
| . |/ |
| ±---------±---------+ ±----------±---------+ |
| | Inbound Handler 2 | | Outbound Handler M-1 | |
| ±---------±---------+ ±----------±---------+ |
| /|\ | |
| | |/ |
| ±---------±---------+ ±----------±---------+ |
| | Inbound Handler 1 | | Outbound Handler M | |
| ±---------±---------+ ±----------±---------+ |
| /|\ | |
±--------------±----------------------------------±--------------+
| |/
±--------------±----------------------------------±--------------+
| | | |
| [ Socket.read() ] [ Socket.write() ] |
|
±------------------------------------------------------------------+
複製代碼這是ChannelPipeline的註釋,我覺得已經足夠形象了。
所以Channel對象的作用,就是把我們對流的處理邏輯串聯起來,然後讓接收的Socket按照串聯起來的邏輯運行。

在瞭解了這三個關鍵類的作用之後,在結合上一篇的服務端代碼,我們可以嘗試着勾畫一下Netty框架的處理流程。

首先有一個單獨EventLoop(boss)會負責網絡連接的接收,在接收到網絡連接之後會把該連接傳遞給EventLoopGroup(worker)。
然後該EventLoopGroup(worker)會均勻的分配網絡連接給內部持有的EventLoop去處理。
EventLoop在獲取了連接之後會不停的關注連接的讀寫事件,如果有準備完畢的讀寫事件,則按照Channel內部的Pipline進行鏈式處理。

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