NIO 之 Selector實現原理
NIO 之 Channel實現原理
NIO 之 ByteBuffer實現原理服務器
全部的讀寫IO都是阻塞操做。網絡
select/poll
從程序的角度解釋:
將 channel 註冊到 seletor 上,經過輪詢channel是否就緒,將就緒的channel返回。多線程
epoll
將 channel 註冊到 selector 上,基於回調的方式(相似監聽者模式),告知selector哪些 channel 已經就緒,而後將就緒的 channel 返回。異步
對比 select/poll 和 epoll 咱們發現epoll效率更高。
若是 select/poll 中註冊了大量的 channel,就要不停的輪詢每一個channel,來判斷那些channel已經就緒。而 epoll 則不須要輪詢。性能
jdk1.4 是使用的 select/poll 模型
jdk1.5 之後把select/poll 改成了epoll模型spa
只須要通知內核要執行什麼操做,內核執行完成後通知你已經執行完成。.net
下面分析下 阻塞I/O、NIO、AIO的數據處理流程線程
從程序調用Socket.getInputStream()方法開始一直阻塞到程序有可讀數據。
阻塞期間程序不能作任何操做。因爲網絡的傳輸效率問題,程序基本上都是在等待網絡數據傳輸,所以 阻塞I/O 效率很低。blog
若是客戶端有多個用戶同時訪問服務器,咱們通常會開啓多線程進行處理,客戶端的請求。以下圖:get
客戶端請求和服務器線程是一對一進行處理的,大量用戶同時訪問會形成服務器上建立大量的線程(線程上下文切換問題),可能致使服務器崩潰。
通常咱們會採用線程池進行處理請求。
程序須要調用Seletor.select()方法,阻塞獲取就緒的channel。而後從channel中讀取數據作響應的處理。這樣一個線程就能夠處理多個請求,程序只須要處理已經就緒的channel就ok了。
程序調用AIO的accept方法並傳入Completionhandler,該方法是非阻塞方法。
等數據準備完成後回調Completionhandler處理響應操做。
程序只須要把具體的操做告知AIO就能夠了,具體操做AIO來幫助你來操做。
AIO在性能上相對於NIO沒有本質的提高。 AIO只是幫助你從內核中將數據複製到用戶空間中,並調用你傳入的回調方法。 NIO 是須要程序本身從內核中將數據複製到用戶空間中,並須要程序本身調用相應的處理邏輯。