NIO 是爲了彌補 IO 操做的不足而誕生的。主要特徵是管道(channel)、緩衝(Buffer)、選擇器(Selector)。緩存
channel併發
至關於傳統 IO 中的流,到任何目的地的數據都要經過一個 channel 對象。Buffer 實際是一個容器對象。線程
Buffer對象
八大基本數據類型,除了 Boolean ,都有緩衝區類型:基本類型+Buffer。事件
Selector資源
選擇器用於監聽多個管道的事件。it
傳統的阻塞 IO 能夠很方便知道何時讀寫,對非阻塞 IO 通道,能夠用選擇器,知道管道準備好了。io
上面是 NIO 的幾個特徵的概論,那麼 NIO 與 IO 之間的優缺點是什麼?效率
區別是有兩點:容器
首先解釋第一點,IO 面向流是一字節一字節的處理和操做。一個輸入和輸出流都是一個字節進行。致使了字節的輸入和輸出效率不高。
NIO 面向快,生產與消費都是一個數據快,相比於按字節處理數據要快得多。同時 NIO 採用了「預讀」的方式,當你讀取一部分數據時,它會猜想你下一步要讀那些數據,提早緩存下來。
第二點,IO 是阻塞的,當一個線程調用 read或者 write 時,線程被阻塞,只要等數據讀完或者寫完,線程才能再次被調用。
NIO ,使用一個線程發送讀取數據,沒有獲得響應以前,線程是空閒的。此時線程能夠去執行其餘任務。
NIO 的缺點是,由於 NIO 是面向緩存區操做,每次處理都是在緩衝區中處理的,問題是每次操做都必須判斷緩衝區中的數據是否已經處理完整,由於只讀取一部分的數據進行處理,是沒有意義的,因此每次數據處理以前都要檢測緩衝區數據。
NIO 與 IO 的應用場景
NIO:同時打開上萬鏈接,這些鏈接只會發送少許的數據,選擇 NIO 更合適。
IO:少許鏈接,每一個鏈接發送大量數據,選擇傳統 IO 更合適,
判斷依據是數據處理的響應時間、檢測緩衝區數據的時間。
有一個網友講的生動的例子:
之前的流老是堵塞的,一個線程只要對它進行操做,其它操做就會被堵塞,也就至關於水管沒有閥門,你伸手接水的時候,無論水到了沒有,你就都只能耗在接水(流)上。
nio的Channel的加入,至關於增長了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管裏流出來的水,均可以獲得妥
善接納,這個關鍵之處就是增長了一個接水工,也就是Selector,他負責協調,也就是看哪根水管有水了的話,在當前水管的水接到必定程度的時候,就切換一下:臨時關上當
前水龍頭,試着打開另外一個水龍頭(看看有沒有水)。
當其餘人須要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其餘人雖然也可能要等,但不會在現場等,而是回家等,能夠作
其它事去,水接滿了,接水工會通知他們。
這其實也是很是接近當前社會分工細化的現實,也是統分利用現有資源達到併發效果的一種很經濟的手段,而不是動不動就來個並行處理,雖然那樣是最簡單的,但也是最浪費資源的方式。