1. 程式人生 > >IO、NIO、AIO 內部原理分析

IO、NIO、AIO 內部原理分析

相關文章

阻塞IO

所有的讀寫IO都是阻塞操作。

多路複用模型

  • select/poll
    從程式的角度解釋:
    將 channel 註冊到 seletor 上,通過輪詢channel是否就緒,將就緒的channel返回。

  • epoll
    將 channel 註冊到 selector 上,基於回撥的方式(類似監聽者模式),告知selector哪些 channel 已經就緒,然後將就緒的 channel 返回。

select/poll 和 epoll 效能分析

對比 select/poll 和 epoll 我們發現epoll效率更高。
如果 select/poll 中註冊了大量的 channel,就要不停的輪詢每個channel,來判斷那些channel已經就緒。而 epoll 則不需要輪詢。

jdk1.4 是使用的 select/poll 模型
jdk1.5 以後把select/poll 改為了epoll模型

非同步 I/O

只需要通知核心要執行什麼操作,核心執行完成後通知你已經執行完成。

下面分析下 阻塞I/O、NIO、AIO的資料處理流程

阻塞I/O 資料處理流程

Paste_Image.png
從程式呼叫Socket.getInputStream()方法開始一直阻塞到程式有可讀資料。
阻塞期間程式不能做任何操作。由於網路的傳輸效率問題,程式基本上都是在等待網路資料傳輸,因此 阻塞I/O 效率很低。

如果客戶端有多個使用者同時訪問伺服器,我們一般會開啟多執行緒進行處理,客戶端的請求。如下圖:

Paste_Image.png
客戶端請求和伺服器執行緒是一對一進行處理的,大量使用者同時訪問會造成伺服器上建立大量的執行緒(執行緒上下文切換問題),可能導致伺服器崩潰。
一般我們會採用執行緒池進行處理請求。

2. NIO 資料處理流程

NIO 實現原理
程式需要呼叫Seletor.select()方法,阻塞獲取就緒的channel。然後從channel中讀取資料做響應的處理。這樣一個執行緒就可以處理多個請求,程式只需要處理已經就行的channel就ok了。

3.AIO 資料處理流程

AIO 實現原理

程式呼叫AIO的accept方法並傳入Completionhandler,該方法是非阻塞方法。
等資料準備完成後回撥Completionhandler處理響應操作。

程式只需要把具體的操作告知AIO就可以了,具體操作AIO來幫助你來操作。

NIO 和 AIO 效能上對比

AIO在效能上相對於NIO沒有本質的提升。
AIO只是幫助你從核心中將資料複製到使用者空間中,並呼叫你傳入的回撥方法。
NIO 是需要程式自己從核心中將資料複製到使用者空間中,並需要程式自己呼叫相應的處理邏輯。