推薦:Java網絡程式設計彙總
Java網絡程式設計-NIO原理
Java NIO原理與簡單實作
正文
NIO 簡介
NIO有兩種解釋:一種叫非阻塞IO(Non-blocking I/O),另一種叫新的IO(New I/O),其實是同一個概念。它是一種同步非阻塞的I/O模型,也是I/O多路複用的基礎,已經被越來越多地應用到大型應用伺服器,成為解決高并發與大量連接配接、I/O處理問題的有效方式。
NIO是一種基于
通道
和
緩沖區
的I/O方式,它可以使用Native函數庫直接配置設定堆外記憶體(差別于JVM的運作時資料區),然後通過一個存儲在Java堆裡面的
DirectByteBuffer
對象作為這塊記憶體的直接引用進行操作。這樣能在一些場景顯著提高性能,因為避免了在Java堆和Native堆中來回複制資料。
NIO元件
NIO主要有三大核心部分:
Channel(通道)
,
Buffer(緩沖區)
,
Selector(選擇器)
。傳統IO是基于
位元組流
和
字元流
進行操作(基于流
Stream
),而NIO基于
Channel
和
Buffer
進行操作,資料總是從通道讀取到緩沖區中,或者從緩沖區寫入到通道中。
Selector
用于監聽多個通道的事件(比如:連接配接打開,資料到達)。是以,單個線程就可以監聽多個資料通道。
-
(緩沖區)是一個用于存儲特定基本類型資料的容器。除了boolean外,其餘每種基本類型都有一個對應的Buffer
類。Buffer
類的子類有Buffer
, ByteBuffer
, CharBuffer
, DoubleBuffer
, FloatBuffer
, IntBuffer
, LongBuffer
。ShortBuffer
-
(通道)表示到實體,如硬體裝置、檔案、網絡套接字或可以執行一個或多個不同 I/O 操作(如讀取或寫入)的程式元件的開放的連接配接。Channel
接口的常用實作類有Channel
(對應檔案IO)、FileChannel
(對應UDP)、DatagramChannel
和SocketChannel
(對應TCP的用戶端和伺服器端)。ServerSocketChannel
和IO中的Channel
(流)是差不多一個等級的。隻不過Stream
是單向的,譬如:Stream
, InputStream
。而OutputStream
是雙向的,既可以用來進行讀操作,又可以用來進行寫操作。Channel
-
(選擇器)用于監聽多個通道的事件(比如:連接配接打開,資料到達)。是以,單個的線程可以監聽多個資料通道。即用選擇器,借助單一線程,就可對數量龐大的活動I/O通道實施監控和維護。Selector
基于
阻塞式I/O
的多線程模型中(
BIO模型
),Server為每個Client連接配接建立一個處理線程,每個處理線程阻塞式等待可能達到的資料,一旦資料到達,則立即處理請求、傳回處理結果并再次進入等待狀态。由于每個Client連接配接有一個單獨的處理線程為其服務,是以可保證良好的響應時間。但當系統負載增大(并發請求增多)時,Server端需要的線程數會增加,對于作業系統來說,線程之間上下文切換的開銷很大,而且每個線程都要占用系統的一些資源(如記憶體)。是以,使用的線程數量盡量不用太多。
但是,現代的作業系統和CPU在多任務方面表現的越來越好,是以多線程的開銷随着時間的推移,變得越來越小了。實際上,如果一個CPU有多個核心,不使用多任務可能是在浪費CPU能力。
BIO模型的處理方式,一個線程處理一個網絡連接配接,如下圖所示:
NIO模型的處理方式,一個線程可以管理多個網絡連接配接,如下圖所示: