Java 網絡通信模型 BIO、NIO、AIO


參照 UNIX 五大 I/O 模型來理解。

本文整理自以下文章:
https://blog.csdn.net/ty497122758/article/details/78979302
https://blog.csdn.net/caohongshuang/article/details/79455391
http://www.imooc.com/article/265871

1. BIO

BIO 是 JDK1.4 之前的 IO 模型,它是基於流模型實現的,交互的方式是同步阻塞方式,也就是說在讀入輸入流或者輸出流時,在讀寫動作完成之前,線程會一直阻塞在那裏,它們之間的調用是可靠的線性順序。它的優點就是代碼比較簡單、直觀;缺點就是 I/O 的效率和擴展性很低,容易成爲應用性能瓶頸。

BIO的服務端通信模型:採用BIO通信模型的服務端,通常由一個獨立的Acceptor線程負責監聽客戶端的連接,它接收到客戶端連接請求之後爲每個客戶端創建一個新的線程進行鏈路處理,處理完成後,通過輸出流返回應答給客戶端,線程銷燬。即典型的一請求一應答通信模型。
傳統BIO通信模型圖:
在這裏插入圖片描述
該模型最大的問題就是缺乏彈性伸縮能力,當客戶端併發訪問量增加後,服務端的線程個數和客戶端併發訪問數呈1:1的正比關係,Java中的線程也是比較寶貴的系統資源,線程數量快速膨脹後,系統的性能將急劇下降,隨着訪問量的繼續增大,系統最終就死掉了。

2. NIO

NIO 是 Java 1.4 引入的 java.nio 包,提供了 Channel、Selector、Buffer 等新的抽象,可以構建多路複用的、同步非阻塞 IO 程序,同時提供了更接近操作系統底層高性能的數據操作方式。

緩衝區 Buffer
在這裏插入圖片描述
Buffer是一個對象,包含一些要寫入或者讀出的數據。在NIO庫中,所有數據都是用緩衝區處理的。在讀取數據時,它是直接讀到緩衝區中的;在寫入數據時,也是寫入到緩衝區中。任何時候訪問NIO中的數據,都是通過緩衝區進行操作。

緩衝區實際上是一個數組,並提供了對數據結構化訪問以及維護讀寫位置等信息。

具體的緩存區有這些:ByteBuffe、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。他們實現了相同的接口:Buffer。

通道 Channel

在這裏插入圖片描述
我們對數據的讀取和寫入要通過Channel,它就像水管一樣,是一個通道。通道不同於流的地方就是通道是雙向的,可以用於讀、寫和同時讀寫操作。

底層的操作系統的通道一般都是全雙工的,所以全雙工的Channel比流能更好的映射底層操作系統的API。

Channel主要分兩大類:

  • SelectableChannel:用於網絡讀寫

  • FileChannel:用於文件操作

多路複用器 Selector
Selector提供選擇已經就緒的任務的能力:Selector會不斷輪詢註冊在其上的Channel,如果某個Channel上面發生讀或者寫事件,這個Channel就處於就緒狀態,會被Selector輪詢出來,然後通過SelectionKey可以獲取就緒Channel的集合,進行後續的I/O操作。

一個Selector可以同時輪詢多個Channel,因爲JDK使用了epoll()代替傳統的select實現,所以沒有最大連接句柄1024/2048的限制。所以,只需要一個線程負責Selector的輪詢,就可以接入成千上萬的客戶端。
在這裏插入圖片描述
就這樣 NIO 的多路複用就大大提升了服務器端響應高併發的能力。

3. AIO

AIO 是 Java 1.7 之後引入的包,是 NIO 的升級版本,提供了異步非阻塞的 IO 操作方式,所以人們叫它 AIO(Asynchronous IO),異步 IO 是基於事件和回調機制實現的,也就是應用操作之後會直接返回,不會阻塞在那裏,當後臺處理完成,操作系統會通知相應的線程進行後續的操作。

與NIO不同,當進行讀寫操作時,只須直接調用API的read或write方法即可。這兩種方法均爲異步的,對於讀操作而言,當有流可讀取時,操作系統會將可讀的流傳入read方法的緩衝區,並通知應用程序;對於寫操作而言,當操作系統將write方法傳遞的流寫入完畢時,操作系統主動通知應用程序。 即可以理解爲,read/write方法都是異步的,完成後會主動調用回調函數。 在JDK1.7中,這部分內容被稱作NIO.2,主要在java.nio.channels包下增加了下面四個異步通道:

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousDatagramChannel
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章