在學習NIO之前,有必要將它與Java IO進行比較,以瞭解兩個包之間的差別。
下麵表格列出了Java IO和NIO之間的主要區別:
IO | NIO |
---|---|
基於阻塞I/O操作 | 基於非阻塞I/O操作 |
面向流的 | 面向緩存的 |
通道不可用 | 通道可用於非阻塞I/O操作 |
選擇器不可用 | 選擇器可用於非阻塞I/O操作 |
阻塞與非阻塞I/O
阻塞I/O
阻塞IO等待數據寫入或返回前的讀取。Java IO的各種流是阻塞的。這意味著當線程調用write()
或read()
時,線程會被阻塞,直到有一些數據可用於讀取或數據被完全寫入。
非阻塞I/O
非阻塞IO不等待返回前讀取或寫入數據。 Java NIO非阻塞模式允許線程請求向通道寫入數據,但不等待它被完全寫入。允許線程繼續進行,並做其他事情。
面向流與面向緩衝
面向流
Java IO是面向流的I/O,這意味著我們需要從流中讀取一個或多個位元組。它使用流來在數據源/槽和java程式之間傳輸數據。使用此方法的I/O操作較慢。
下麵來看看在Java程式中使用輸入/輸出流的數據流圖:
面向緩衝
Java NIO是面向緩存的I/O方法。 將數據讀入緩衝器,使用通道進一步處理數據。 在NIO中,使用通道和緩沖區來處理I/O操作。
通道和流之間的主要區別是:
- 流可以用於單向數據傳輸。
- 通道提供雙向數據傳輸。
因此,通過在java NIO中引入通道,可以執行非阻塞I/O操作。
下麵看看通道,緩衝區,java程式,數據源和數據接收器之間的相互作用 -
通道(Channels)
在Java NIO中,通道是在實體和位元組緩衝區之間有效傳輸數據的媒介。 它從一個實體讀取數據,並將其放在緩衝區塊中以供消費。
通道作為Java NIO提供的網關來訪問I/O機制。通常,通道與操作系統檔描述符具有一對一關係,用於提供平臺獨立操作功能。
NIO通道基礎
通道使用本地代碼執行實際工作。通道介面允許我們以便攜和受控的方式訪問低級I/O服務。
在層次結構的頂部,通道介面如下所示:
package java.nio.channels;
public interface Channel{
public boolean isclose();
public void Open() throws IOException;
}
正如在上述通道介面中看到的,所有通道中有常見的兩個操作:
- 檢查通道是否關閉(
isclose()
) - 打開關閉通道(
close()
)
選擇器(Selectors)
在Java NIO中,選擇器是可選擇通道的多路複用器,可用作可以進入非阻塞模式的特殊類型的通道。它可以檢查一個或多個NIO通道,並確定哪個通道準備好進行通信,即讀取或寫入。
選擇器(Selectors)的用途是什麼?
選擇器用於使用單個線程處理多個通道。因此,它需要較少的線程來處理這些通道。
線程之間的切換對於操作系統來說是昂貴的。 因此,為了提高系統效率選擇器是有用的。
下麵來看看使用選擇器來處理3
個通道的線程的示意圖:
創建選擇器
可以通過調用Selector.open()
方法創建一個選擇器,如下代碼所示:
Selector selector = Selector.open();