您好,登錄后才能下訂單哦!
本篇內容介紹了“什么是NIO”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
NIO( No-blocking I/O)顧名思義他是非阻塞的(其實 可以設置阻塞與非阻塞兩種模式 ) ,普通的IO流是阻塞的 當一個線程調用 read() 或 write()時,該線程被 阻塞,直到有一些數據被讀取,或數據完全寫入,該線程在此期間不能再干任何事情了。而 NIO 是非阻塞模式, 若沒有數據可用時,該線程可以進行其他任務,單獨的線程可以管理多個輸入輸出通道,大大提高了CPU使用率。
IO是面向流的,NIO是面向緩沖的, 發送給一個通道的所有數據都必須首先放到緩沖區中,同樣地,從通道中讀取的任何數據都要先讀到緩沖區中。也就是說,不會直接對通道進行讀寫數據,而是要先經過緩沖區。
Selector 選擇器
NIO 的選擇器允許一個單獨的線程來監視多個輸入通道,這個線程使用一個選擇器 Selector 通過輪詢的方式去監聽多個通道 Channel 上的事件,從而讓一個線程就可以處理多個事件。
Channels
通道 是對原 I/O 包中的流的模擬 ,是一個應用程序和操作系統交互事件,傳遞內容的渠道。 通道與流(Stream)的不同之處在于,流只能在一個方向上移動 , 而通道是雙向的,可以用于讀、寫或者同時用于讀寫。 Channel本身不能直接訪問數據,Channel只能與Buffer進行交互。
所有被 Selector注冊的通道,只能是繼承了 SelectableChannel 類的子類。
buffer 緩沖區
緩沖區用于存儲數據,一般先向buffer寫入數據,buffer會記錄寫下多少數據,在讀取數據之前需要先調用 flip() 從寫模式改成讀模式。讀完了以后需要調用 clear() 清空buffer讓他可以重新被寫入.
構造方法
ByteBuffer buf = ByteBuffer.allocate(1024
);
向buffer寫入數據
writeBuffer.put(str)
從Buffer中讀取數據
//根據緩沖區可讀字節數創建字節數組byte[] bytes = new byte[buffer.remaining()]; //將緩沖區可讀字節數組復制到新建的數組中buffer.get(bytes);
byte aByte = buf.get();
get()屬于相對讀,從 position 位置讀取一個 byte,并將 position+1,為下次讀寫作準備。
byte aByte = buf.get(int index);
屬于絕對讀,讀取 byteBuffer 底層的 bytes 中下標為 index 的 byte,不改 變 position。
Buffer.rewind()將 position 設回 0,所以你可以重讀 Buffer 中的所有數據。limit 保持不變, 仍然表示能從 Buffer 中讀取多少個元素
SelectionKey
每個Channel 向 Selector 注冊時,都將會創建一個 SelectionKey。SelectionKey 將 Channel 與 Selector 建立了 關系,并維護了 channel 事件。
調用cancel 方法取消鍵,取消的鍵不會立即從selector中移除,而是添加到 cancelledKeys 中,在下一次 select 操作時移除它.所以在調用某個key 時,需要使用 isValid 進行 校驗.
在向 Selector 對象注冊事件時, NIO 共定義了四種:OP_READ(讀)、OP_WRITE(寫)、 OP_CONNECT(請求連接)、OP_ACCEPT(接受連接)
OP_READ: 操作系統的讀緩沖區有數據可讀時就緒。
OP_WRITE: 操作系統寫緩沖區有空閑空間時就緒。一般情況下寫緩沖區都有空閑空間,小塊數據直接寫入即可,沒必要注冊該操作類型,否則該條件不 斷就緒浪費 CPU。
OP_CONNECT: 當 SocketChannel.connect()請求連接成功后就緒。該操作只給客戶端 使用。
OP_ACCEPT: 當接收到一個客戶端連接請求時就緒。該操作只給服務器使用。
“什么是NIO”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。