nio是什么


1.nio是java New IO的簡稱,在jdk1.4 里提供的新api。

Sun官方標榜的特性如下:為所有的原始類型提供(Buffer)緩存支持。字符集編碼解碼解決方案。

Channel :一個新的原始I/O抽象。
支持鎖和內存映射文件的文件訪問接口。
提供多路(non-bloking)非阻塞式的高伸縮性網絡I/O 。

2.Buffer&Chanel

Channel和buffer是NIO是兩個最基本的數據類型抽象。

Buffer: 是一塊連續的內存塊。是NIO數據讀或寫的中轉地。
Channel: 數據的源頭或者數據的目的地,用於向buffer提供數據或者讀取buffer數據,buffer對象的唯一接口。

異步I/O支持
例子:

3.其中buffer內部結構如下:

一個buffer主要由position,limit,capacity三個變量來控制讀寫的過程。此三個變量的含義見如下表格:

Buffer常見方法:

flip():寫模式轉換成讀模式,rewind():將position重置為0,一般用於重復讀。
clear():清空buffer,准備再次被寫入(position變成0,limit變成capacity)。
compact():將未讀取的數據拷貝到buffer的頭部位。mark()、reset():mark可以標記一個位置,reset可以重置到該位置。

Buffer常見類型:
ByteBuffer、MappedByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer。

channel常見類型:
FileChannel、DatagramChannel(UDP)、SocketChannel(TCP)、ServerSocketChannel(TCP)

4.一個常見的網絡IO通訊流程如下 :

從該網絡通訊過程來理解一下何為阻塞 :
在以上過程中若連接還沒到來,那么accept會阻塞,程序運行到這里不得不掛起,CPU轉而執行其他線程。在以上過程中若數據還沒准備好,read會一樣也會阻塞。阻塞式網絡IO的特點:多線程處理多個連接。每個線程擁有自己的棧空間並且占用一些CPU時間。每個線程遇到外部為准備好的時候,都會阻塞掉。阻塞的結果就是會帶來大量的進程上下文切換。且大部分進程上下文切換可能是無意義的。比如假設一個線程監聽一個端口,一天只會有幾次請求進來,但是該cpu不得不為該線程不斷做上下文切換嘗試,大部分的切換以阻塞告終。

非阻塞的原理
把整個過程切換成小的任務,通過任務間協作完成。由一個專門的線程來處理所有的IO事件,並負責分發。事件驅動機制:事件到的時候觸發,而不是同步的去監視事件。線程通訊:線程之間通過wait,otify等方式通訊。保證每次上下文切換都是有意義的。減少無謂的進程切換。以下是異步IO的結構:

Reactor就是上面隱喻的售票員角色。每個線程的處理流程大概都是讀取數據、解碼、計算處理、編碼、發送響應。 異步IO核心API Selector
異步IO的核心類,它能檢測一個或多個通道(channel)上的事件,並將事件分發出去。使用一個elect線程就能監聽多個通道上的事件,並基於事件驅動觸發相應的響應。而不需要為每個channel去分配一個線程。SelectionKey

5.如果需要管理同時打開的成千上萬個連接,這些連接每次只是發送少量的數據,例如聊天服務器,實現NIO的服務器可能是一個優勢。同樣,如果你需要維持許多打開的連接到其他計算機上,如P2P網絡中,使用一個單獨的線程來管理你所有出站連接,可能是一個優勢。一個線程多個連接的設計方案如下圖所示:

Java NIO: 單線程管理多個連接,如果你有少量的連接使用非常高的帶寬,一次發送大量的數據,也許典型的IO服務器實現可能非常契合。下圖說明了一個典型的IO服務器設計:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM