Java的 IO 與 NIO

NIO 是爲了彌補 IO 操做的不足而誕生的。主要特徵是管道(channel)、緩衝(Buffer)、選擇器(Selector)。緩存

 

channel併發

至關於傳統 IO 中的流,到任何目的地的數據都要經過一個 channel 對象。Buffer 實際是一個容器對象。線程

 

Buffer對象

八大基本數據類型,除了 Boolean ,都有緩衝區類型:基本類型+Buffer。事件

 

Selector資源

選擇器用於監聽多個管道的事件。it

傳統的阻塞 IO 能夠很方便知道何時讀寫,對非阻塞 IO 通道,能夠用選擇器,知道管道準備好了。io

 

上面是 NIO 的幾個特徵的概論,那麼 NIO 與 IO 之間的優缺點是什麼?效率

區別是有兩點:容器

  1. IO 是面向流的,NIO 是面向塊的。
  2. IO 是阻塞的,NIO 是非阻塞的。

 

首先解釋第一點,IO 面向流是一字節一字節的處理和操做。一個輸入和輸出流都是一個字節進行。致使了字節的輸入和輸出效率不高。

NIO 面向快,生產與消費都是一個數據快,相比於按字節處理數據要快得多。同時 NIO 採用了「預讀」的方式,當你讀取一部分數據時,它會猜想你下一步要讀那些數據,提早緩存下來。

第二點,IO 是阻塞的,當一個線程調用 read或者 write 時,線程被阻塞,只要等數據讀完或者寫完,線程才能再次被調用。

NIO ,使用一個線程發送讀取數據,沒有獲得響應以前,線程是空閒的。此時線程能夠去執行其餘任務。

NIO 的缺點是,由於 NIO 是面向緩存區操做,每次處理都是在緩衝區中處理的,問題是每次操做都必須判斷緩衝區中的數據是否已經處理完整,由於只讀取一部分的數據進行處理,是沒有意義的,因此每次數據處理以前都要檢測緩衝區數據。

 

NIO 與 IO 的應用場景

NIO:同時打開上萬鏈接,這些鏈接只會發送少許的數據,選擇 NIO 更合適。

IO:少許鏈接,每一個鏈接發送大量數據,選擇傳統 IO 更合適,

判斷依據是數據處理的響應時間、檢測緩衝區數據的時間。

 

有一個網友講的生動的例子:

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

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

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

前水龍頭,試着打開另外一個水龍頭(看看有沒有水)。

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

其它事去,水接滿了,接水工會通知他們。

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

相關文章
相關標籤/搜索