Java NIO 概覽

weixin_34054866發表於2018-05-14

一 NIO簡介

Java NIOjava 1.4 之後新出的一套IO介面,這裡的的新是相對於原有標準的Java IO和Java Networking介面。NIO提供了一種完全不同的操作方式。

NIO中的N可以理解為Non-blocking,不單純是New。

它支援面向緩衝的,基於通道的I/O操作方法。 隨著JDK 7的推出,NIO系統得到了擴充套件,為檔案系統功能和檔案處理提供了增強的支援。 由於NIO檔案類支援的這些新的功能,NIO被廣泛應用於檔案處理。

二 NIO的特性/NIO與IO區別

8160928-4c03233484f60c2e
Java NIO基本元件如下

1 Channels and Buffers(通道和緩衝區)

IO是面向流的,NIO是面向緩衝區的

  • 標準的IO程式設計介面是面向位元組流和字元流的。而NIO是面向通道和緩衝區的,資料總是從通道中讀到buffer緩衝區內,或者從buffer緩衝區寫入到通道中;( NIO中的所有I/O操作都是通過一個通道開始的。)
  • Java IO面向流意味著每次從流中讀一個或多個位元組,直至讀取所有位元組,它們沒有被快取在任何地方;
  • Java NIO是面向快取的I/O方法。 將資料讀入緩衝器,使用通道進一步處理資料。 在NIO中,使用通道和緩衝區來處理I/O操作。

2 Non-blocking IO(非阻塞IO)

IO流是阻塞的,NIO流是不阻塞的

  • Java NIO使我們可以進行非阻塞IO操作。比如說,單執行緒中從通道讀取資料到buffer,同時可以繼續做別的事情,當資料讀取到buffer中後,執行緒再繼續處理資料。寫資料也是一樣的。另外,非阻塞寫也是如此。一個執行緒請求寫入一些資料到某通道,但不需要等待它完全寫入,這個執行緒同時可以去做別的事情。

  • Java IO的各種流是阻塞的。這意味著,當一個執行緒呼叫read() 或 write()時,該執行緒被阻塞,直到有一些資料被讀取,或資料完全寫入。該執行緒在此期間不能再幹任何事情了

3 Selectors(選擇器)

NIO有選擇器,而IO沒有。

  • 選擇器用於使用單個執行緒處理多個通道。因此,它需要較少的執行緒來處理這些通道。
  • 執行緒之間的切換對於作業系統來說是昂貴的。 因此,為了提高系統效率選擇器是有用的。

三 讀資料和寫資料方式

通常來說NIO中的所有IO都是從 Channel(通道) 開始的。

從通道進行資料讀取 :建立一個緩衝區,然後請求通道讀取資料。

從通道進行資料寫入 :建立一個緩衝區,填充資料,並要求通道寫入資料。

資料讀取和寫入操作圖示:

8160928-75816f18da2917b7
資料讀取和寫入操作圖示

四 NIO核心元件簡單介紹

NIO包含下面幾個核心的元件:

  • Channels
  • Buffers
  • Selectors

整個NIO體系包含的類遠遠不止這三個,只能說這三個是NIO體系的“核心API”。

通道

在Java NIO中,主要使用的通道如下(涵蓋了UDP 和 TCP 網路IO,以及檔案IO):

  • DatagramChannel
  • SocketChannel
  • FileChannel
  • ServerSocketChannel

緩衝區

在Java NIO中使用的核心緩衝區如下(覆蓋了通過I/O傳送的基本資料型別:byte, char、short, int, long, float, double ,long):

  • ByteBuffer
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • FloatBuffer
  • DoubleBuffer
  • LongBuffer

選擇器

Java NIO提供了“選擇器”的概念。這是一個可以用於監視多個通道的物件,如資料到達,連線開啟等。因此,單執行緒可以監視多個通道中的資料。

如果應用程式有多個通道(連線)開啟,但每個連線的流量都很低,則可考慮使用它。 例如:在聊天伺服器中。

下面是一個單執行緒中Slector維護3個Channel的示意圖:

8160928-f163f5eafa276005
執行緒使用選擇器來處理3個通道

要使用Selector的話,我們必須把Channel註冊到Selector上,然後就可以呼叫Selector的select()方法。這個方法會進入阻塞,直到有一個channel的狀態符合條件。當方法返回後,執行緒可以處理這些事件。

參考:

官方JDK相關文件

谷歌搜尋排名第一的Java NIO教程

Java NIO 與 IO之間的區別

《Java程式設計師修煉之道》