Java中NIO和IO區別和適用場景

NIO是爲了彌補IO操做的不足而誕生的,NIO的一些新特性有:非阻塞I/O,選擇器,緩衝以及管道。管道(Channel),緩衝(Buffer) ,選擇器( Selector)是其主要特徵。服務器

 

概念解釋:併發

Channel——管道實際上就像傳統IO中的流,到任何目的地(或來自任何地方)的全部數據都必須經過一個 Channel 對象。一個 Buffer 實質上是一個容器對象。線程

Selector——選擇器用於監聽多個管道的事件,使用傳統的阻塞IO時咱們能夠方便的知道何時能夠進行讀寫,而使用非阻塞通道,咱們須要一些方法來知道何時通道準備好了,選擇器正是爲這個須要而誕生的。對象

NIO和傳統的IO有什麼區別呢?事件

1,IO是面向流的,NIO是面向塊(緩衝區)的。資源

        IO面向流的操做一次一個字節地處理數據。一個輸入流產生一個字節的數據,一個輸出流消費一個字節的數據。,致使了數據的讀取和寫入效率不佳;get

        NIO面向塊的操做在一步中產生或者消費一個數據塊。按塊處理數據比按(流式的)字節處理數據要快得多,同時數據讀取到一個它稍後處理的緩衝區,須要時可在緩衝區中先後移動。這就增長了處理過程當中的靈活性。通俗來講,NIO採起了「預讀」的方式,當你讀取某一部分數據時,他就會猜想你下一步可能會讀取的數據而預先緩衝下來。it

2,IO是阻塞的,NIO是非阻塞的。io

        對於傳統的IO,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據徹底寫入。該線程在此期間不能再幹任何事情了。效率

        而對於NIO,使用一個線程發送讀取數據請求,沒有獲得響應以前,線程是空閒的,此時線程能夠去執行別的任務,而不是像IO中那樣只能等待響應完成。

3,NIO和IO適用場景

        NIO是爲彌補傳統IO的不足而誕生的,可是尺有所短寸有所長,NIO也有缺點,由於NIO是面向緩衝區的操做,每一次的數據處理都是對緩衝區進行的,那麼就會有一個問題,在數據處理以前必需要判斷緩衝區的數據是否完整或者已經讀取完畢,若是沒有,假設數據只讀取了一部分,那麼對不完整的數據處理沒有任何意義。因此每次數據處理以前都要檢測緩衝區數據。

那麼NIO和IO各適用的場景是什麼呢?

        若是須要管理同時打開的成千上萬個鏈接,這些鏈接每次只是發送少許的數據,例如聊天服務器,這時候用NIO處理數據多是個很好的選擇。

        而若是隻有少許的鏈接,而這些鏈接每次要發送大量的數據,這時候傳統的IO更合適。使用哪一種處理數據,須要在數據的響應等待時間和檢查緩衝區數據的時間上做比較來權衡選擇。

4,通俗解釋

最後,對於NIO和傳統IO,有一個網友講的生動的例子:

之前的流老是堵塞的,一個線程只要對它進行操做,其它操做就會被堵塞,也就至關於水管沒有閥門,你伸手接水的時候,無論水到了沒有,你就都只能耗在接水(流)上。

nio的Channel的加入,至關於增長了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管裏流出來的水,均可以獲得妥

善接納,這個關鍵之處就是增長了一個接水工,也就是Selector,他負責協調,也就是看哪根水管有水了的話,在當前水管的水接到必定程度的時候,就切換一下:臨時關上當前水龍頭,試着打開另外一個水龍頭(看看有沒有水)。

當其餘人須要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其餘人雖然也可能要等,但不會在現場等,而是回家等,能夠作其它事去,水接滿了,接水工會通知他們。

這其實也是很是接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。

相關文章
相關標籤/搜索