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