【Netty】NIO 简介 ( NIO 模型 | NIO 三大组件 | 选择器 Selector | 通道 Channel | 缓冲区 Buffer | NIO 组件分配 | 缓冲区示例 )
文章目錄
- I . NIO 模型
- II . NIO 三大組件交互流程
- III . NIO 緩沖區
- IV . NIO 與 BIO 對比
- V . NIO 線程分配
- VI . 緩沖區 ( Buffer ) 示例
I . NIO 模型
NIO 簡介 :
① NIO 概念 : NIO 全稱為 Non-Blocking IO , 是非阻塞 IO , 與 BIO ( Blocking IO / 阻塞 IO ) 相對應 ;
② NIO 相對于 BIO 的改進 : NIO 在 BIO 的基礎上 , 增加了 IO 的性能 ;
③ NIO 模型特點 : NIO 是同步非阻塞模型 , BIO 是同步阻塞模型 ;
④ NIO API 位置 : 在 Java 中 , NIO 定義在 java.nio 包中 ;
⑤ NIO 三大組件 :
- 通道 Channel : 相當于 BIO 中的 Socket , 用于傳輸數據 , 向客戶端讀寫數據 ,
- 緩沖區 Buffer : 每個通道 ( Channel ) 都維護了一個數據緩沖區 ( Buffer ) ; 通道 ( Channel ) 可以讀寫 緩沖區 ( Buffer ) 中的數據 , 是雙向的 ; 客戶端 也是讀寫 緩沖區 ( Buffer ) 中的數據 ; 緩沖區 ( Buffer ) 是 通道 ( Channel ) 與 客戶端 之間的緩沖區 ;
- 選擇器 Selector : 選擇器 ( Selector ) 根據客戶端請求 , 選擇指定的 通道 ( Channel ) 為客戶端進行服務 ;
II . NIO 三大組件交互流程
NIO 服務器端 交互流程 :
① 啟動線程 : 服務器端啟動一個線程 ;
② 選擇器 ( Selector ) 遍歷 通道 ( Channel ) : 線程通過 選擇器 ( Selector ) 不同的遍歷各個 通道 ( Channel ) , 如果發現有 客戶端 對應的 通道 ( Channel ) 有網絡請求 , 那么開始處理該 通道 ( Channel ) 相關業務邏輯 ;
③ 通道 ( Channel ) 與 緩沖區 ( Buffer ) 交互 : 通道 ( Channel ) 可以 讀寫 緩沖區 ( Buffer ) 中的數據 ;
④ 緩沖區 ( Buffer ) 與 客戶端交互 : 緩沖區 ( Buffer ) 與 客戶端 進行數據讀寫交互 ;
III . NIO 緩沖區
緩沖區 機制 : 緩沖區 ( Buffer ) 向上與 通道 ( Channel ) 進行數據讀寫交互 , 向下與 客戶端 進行數據讀寫交互 , 客戶端 與 通道 ( Channel ) 不直接進行數據通信 ;
① 緩沖區 ( Buffer ) 作用 : 緩沖區 ( Buffer ) 是實現非阻塞機制的重要途徑 ;
② 編程風格 : NIO 也稱為 面向 緩沖區 編程 ;
③ BIO 阻塞機制 : BIO 中 客戶端 與 服務器端 進行交互 , 需要阻塞等待服務器的響應 , 服務器在建立連接后 , 也需要阻塞等待客戶端的后續數據 ;
④ NIO 非阻塞機制 : 客戶端請求服務器端后 , 將請求數據寫入服務器端的 緩沖區 ( Buffer ) 中 , 服務器端通過 選擇器 ( Selector ) 輪詢 通道 ( Channel ) , 查詢 緩沖區 ( Buffer ) 中是否有請求數據 , 客戶端不用阻塞等待服務器端響應 , 服務器端也不用阻塞等待客戶端的請求 , 因此這里實現了非阻塞機制 ;
非阻塞說明 : 當選擇器 ( Selector ) 選擇某個 通道 ( Channel ) 時 , 服務器端線程 從通道 ( Channel ) 中讀取用戶請求的數據 , 讀取完畢之后 , 處理該請求處理 , 如果沒有讀取到用戶請求數據 , 就會輪詢其它的 通道 ( Channel ) , 如果所有的 通道 ( Channel ) 都沒有事件觸發 , 線程做其它事情 , 不會在此阻塞等待用戶數據 ;
基于事件驅動 : 選擇器 ( Selector ) 可以感知到 通道 ( Channel ) 中的事件 , 線程就會處理與該通道 ( Channel ) 相關業務 , 如果 通道 ( Channel ) 沒有觸發事件 , 那么線程去做其它事 ;
IV . NIO 與 BIO 對比
1 . 數據處理方式對比 :
① BIO 數據處理方式 : BIO 以 流的方式讀寫數據 , 輸入流 讀取數據 , 輸出流 寫出數據 ; 輸入流 和 輸出流 又分別有 字節流 , 字符流 分類 ;
② NIO 數據處理方式 : NIO 以 緩沖區 ( Buffer ) 數據塊的方式處理數據 , 該處理數據的效率 , 遠遠高于以 流 的方式讀寫數據的效率 ;
- 客戶端 與 服務器交互時 , 客戶端將數據 寫入到 緩沖區 ( Buffer ) , 等待服務器端 通道 ( Channel ) 讀取該緩沖區的數據 ;
- 服務器 與 客戶端交互時 , 服務器將數據 通過 通道 ( Channel ) 寫出到緩沖區中 , 等待 客戶端 讀取 ;
2 . IO 模型 阻塞類型對比 : BIO 是 同步阻塞 型 IO ; NIO 是 同步非阻塞 型 IO ;
V . NIO 線程分配
BIO 模型 : 在 BIO 模型中 , 如果 一萬 客戶端 與 服務器端保持連接通信 , 并進行數據交互 , 就需要有 一萬個線程 維護這些操作 ;
BIO 模型中 , 100001000010000 客戶端連接 , 對應 100001000010000 線程 ;
NIO 模型 : 在 NIO 模型中 , 如果 一萬 客戶端 與 服務器端保持連接通信 , 并進行數據交互 , 那么假設分配 100100100 個線程 , 每個線程都有對應的 選擇器 ( Selector ) , 每個 選擇器 ( Selector ) 輪詢 100100100 個 通道 ( Channel ) , 每個 通道 ( Channel ) 對應 一個 緩沖區 ( Buffer ) ;
NIO 模型中 , 100001000010000 客戶端連接 , 對應 100001000010000 個緩沖區 ( Buffer ) , 100001000010000 個 通道 ( Channel ) , 100100100 個線程 ;
VI . 緩沖區 ( Buffer ) 示例
Buffer 有 777 個子類 , 分別對應 888 大基礎數據 ( Boolean 除外 ) , 這里使用 IntBuffer 作示例說明 ;
緩沖區 ( Buffer ) 代碼示例 :
需求 : 創建一個 存放 int 數據的 緩沖區 ( Buffer ) , 其容量為 888 , 將 888 個 int 值存入緩沖區 , 翻轉后 , 按照存放順序打印出來 ;
import java.nio.IntBuffer;public class BufferDemo {public static void main(String[] args) {//創建一個存儲 Int 類型數據的 Buffer , 可以存儲 8 個 Int 數據IntBuffer buffer = IntBuffer.allocate(8);//向 Buffer 中寫入數據for(int i = 0; i < buffer.capacity(); i ++){buffer.put(i);}//從 Buffer 中取出數據//先將 Buffer 翻轉一下 , 然后讀取 , 讀出的數據與存儲的數據順序一樣buffer.flip();//循環讀取 buffer 中的 Int 數據, 維護了一個索引 ,//代表當前操作的數據索引 , 即 positionwhile (buffer.hasRemaining()){System.out.println("position " + buffer.position() + " . " + buffer.get());}} }執行結果 :
position : 0 . 0 position : 1 . 1 position : 2 . 2 position : 3 . 3 position : 4 . 4 position : 5 . 5 position : 6 . 6 position : 7 . 7總結
以上是生活随笔為你收集整理的【Netty】NIO 简介 ( NIO 模型 | NIO 三大组件 | 选择器 Selector | 通道 Channel | 缓冲区 Buffer | NIO 组件分配 | 缓冲区示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Netty】IO 模型简介 ( Net
- 下一篇: 【Netty】NIO 缓冲区 ( Buf