一.nio相對於bio來說,是新io,或者非阻塞io,是核心系統公升級後產物
上面**我們看到,serversocketchannel.accept()設定成非阻塞後,如果沒有客戶端連線,**會不停地死迴圈執行。同理,socketchannel.configureblocking(false); socketchannel.read方法和socketchannel.write方法也是非阻塞的,有需要讀寫的資料,直接讀寫,沒有的話**直接往下執行,空迴圈,然後再進行下一次迴圈看看有沒有要讀寫的資料。
有沒有發現乙個問題,一旦**不阻塞了,方法accept、read、write等就要放在迴圈體中,條件不滿足時,只能不停的空輪循。這種方式顯然不好,怎麼解決呢?可不可以統一交給乙個物件來處理,讓它來負責監控物件serversocketchannel、socketchannel中有沒有需要處理的事情
二.select和poll
(1)select==>時間複雜度o(n)
select()的機制中提供一種fd_set的資料結構,long型別的陣列,每乙個陣列元素都能與已開啟的檔案控制代碼(不管是socket控制代碼,還是其他檔案或命名管道或裝置控制代碼)建立聯絡,當呼叫select()時,由核心根據io狀態修改fd_set的內容,由此來通知執行了select()的程序哪一socket或檔案可讀,無差別輪詢所有控制代碼,找出需要處理的,對他們進行操作。select無差別輪詢複雜度,同時處理的流越多,無差別輪詢時間就越長
(2)poll==>時間複雜度o(n)
poll本質上和select沒有區別,管理多個描述符也是進行輪詢,但是它沒有最大連線數的限制,基於鍊錶來儲存的
三.epoll和多路復用器
epoll可以理解為event poll,epoll會把哪個流發生了怎樣的i/o事件通知我們,複雜度降低到了o(1),不再是盲目的輪循所有開啟的流
不知道大家有沒有想到***,將一堆觀察者、被觀察者註冊到廣播器上面,當被觀察者有事件發生時,利用廣播器通知特定的觀察者,epoll類似於觀察者模式
select,poll,epoll都是io多路復用的機制,i/o多路復用就通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程式進行相應的讀寫操作。多路復用,說白了,就是指乙個物件可以反覆監控著多個鏈路通道流上面的事件情況,selector
四.bytebuffer
緩衝區(buffer)就是在記憶體中(堆內或堆外)預留指定大小的儲存空間用來對輸入/輸出(i/o)的資料作臨時儲存資料的緩衝區,好處:
1、減少實際的物理讀寫次數
2、緩衝區在建立時就被分配記憶體,這塊記憶體區域一直被重用,可以減少動態分配和**記憶體的次數
緩衝區直接為通道(channel)服務,寫入資料到通道或從通道讀取資料,面向可讀可寫的緩衝區而不是位元組流,大大提高傳遞的效率,底層本質上是乙個陣列結構
JAVA中的IO同步阻塞和NIO同步非阻塞
ionio 面向流面向緩衝 阻塞io 非阻塞io 無選擇器 1.面向流與面向緩衝2.阻塞與非阻塞 io3.選擇器 selector 最傳統的一種io模型,即在讀寫資料過程中會發生阻塞現象。當使用者執行緒發出io請求之後,核心會去檢視資料是否就緒,如果沒有就緒就會等待資料就緒,而使用者執行緒就會處於阻...
阻塞IO與非阻塞NIO
通常的,對乙個檔案描述符指定的檔案或裝置,有兩種工作方式 阻塞 與非阻塞 所謂阻塞方式的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀,或者暫時不可寫,程式就進入等待 狀態,直到有東西可讀或者可寫為止。而對於非阻塞狀態,如果沒有東西可讀,或者不可寫,讀寫函式馬上返回,而不會等待 一種...
IO與NIO的區別
一 實現方式 傳統io 1.傳統的socket io當客戶端和服務端連線成功後,服務端在進行讀取客戶端傳送的資訊的時候是通過新建執行緒來處理的,由此帶來了乙個問題,當有大量客戶端想服務端傳輸資料的時候,服務端就會啟動大量執行緒,這樣將大大的增加了伺服器的壓力。2.同時,傳統io通訊是阻塞的,即在讀取...