1. 程式人生 > >BIO和NIO的區別

BIO和NIO的區別

BIO:同步阻塞式IO,伺服器實現模式為一個連線一個執行緒,即客戶端有連線請求時伺服器端就需要啟動一個執行緒進行處理,如果這個連線不做任何事情會造成不必要的執行緒開銷,當然可以通過執行緒池機制改善。
NIO:同步非阻塞式IO,伺服器實現模式為一個請求一個執行緒,即客戶端傳送的連線請求都會註冊到多路複用器上,多路複用器輪詢到連線有I/O請求時才啟動一個執行緒進行處理。
AIO(NIO.2):非同步非阻塞式IO,伺服器實現模式為一個有效請求一個執行緒,客戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動執行緒進行處理。

BIO
同步阻塞式IO,相信每一個學習過作業系統網路程式設計或者任何語言的網路程式設計的人都很熟悉,在while迴圈中服務端會呼叫accept方法等待接收客戶端的連線請求,一旦接收到一個連線請求,就可以建立通訊套接字在這個通訊套接字上進行讀寫操作,此時不能再接收其他客戶端連線請求,只能等待同當前連線的客戶端的操作執行完成。

如果BIO要能夠同時處理多個客戶端請求,就必須使用多執行緒,即每次accept阻塞等待來自客戶端請求,一旦受到連線請求就建立通訊套接字同時開啟一個新的執行緒來處理這個套接字的資料讀寫請求,然後立刻又繼續accept等待其他客戶端連線請求,即為每一個客戶端連線請求都建立一個執行緒來單獨處理,大概原理圖就像這樣:

雖然此時伺服器具備了高併發能力,即能夠同時處理多個客戶端請求了,但是卻帶來了一個問題,隨著開啟的執行緒數目增多,將會消耗過多的記憶體資源,導致伺服器變慢甚至崩潰,NIO可以一定程度解決這個問題。


NIO
同步非阻塞式IO,關鍵是採用了事件驅動的思想來實現了一個多路轉換器。
NIO與BIO最大的區別就是隻需要開啟一個執行緒就可以處理來自多個客戶端的IO事件,這是怎麼做到的呢?

就是多路複用器,可以監聽來自多個客戶端的IO事件:
A.若服務端監聽到客戶端連線請求,便為其建立通訊套接字(java中就是通道),然後返回繼續監聽,若同時有多個客戶端連線請求到來也可以全部收到,依次為它們都建立通訊套接字。
B.若服務端監聽到來自已經建立了通訊套接字的客戶端傳送來的資料,就會呼叫對應介面處理接收到的資料,若同時有多個客戶端發來資料也可以依次進行處理。
C.監聽多個客戶端的連線請求和接收資料請求同時還能監聽自己時候有資料要傳送。


總之就是在一個執行緒中就可以呼叫多路複用介面(java中是select)阻塞同時監聽來自多個客戶端的IO請求,一旦有收到IO請求就呼叫對應函式處理。

各自應用場景

到這裡你也許已經發現,一旦有請求到來(不管是幾個同時到還是隻有一個到),都會呼叫對應IO處理函式處理,所以:

(1)NIO適合處理連線數目特別多,但是連線比較短(輕操作)的場景,Jetty,Mina,ZooKeeper等都是基於java nio實現。

(2)BIO方式適用於連線數目比較小且固定的場景,這種方式對伺服器資源要求比較高,併發侷限於應用中。