1. 程式人生 > 程式設計 >深入瞭解Netty【一】BIO、NIO、AIO簡單介紹

深入瞭解Netty【一】BIO、NIO、AIO簡單介紹

引言

在Java中提供了三種IO模型:BIO、NIO、AIO,模型的選擇決定了程式通訊的效能。

1.1、使用場景

  • BIO BIO適用於連線數比較小的應用,這種IO模型對伺服器資源要求比較高。
  • NIO NIO適用於連線數目多、連線時間短的應用,比如聊天、彈幕、伺服器間通訊等應用。
  • AIO AIO適用於連線數目多、連線時間長的應用,比如相簿伺服器。

1.2、BIO

同步並阻塞模型,伺服器會為每一個連線建立一個執行緒,如果連線過多,且執行緒不做任何事情,會極大的浪費資源,示意圖如下:

BIO.png

1.2.1、機制

BIO-工作機制.png
流程:

  1. 伺服器端啟動ServerSocket。
  2. 客戶端啟動Socket對伺服器進行通訊,伺服器會為每個客戶端建立一個執行緒與之通訊。
  3. 客戶端傳送請求,先諮詢伺服器是否有執行緒響應,如果沒有則會等待,或者被拒絕。
  4. 如果有響應,客戶端執行緒會等待請求結束後,再繼續執行。

1.2.2、問題

  • 服務端對於每個請求都要建立獨立的執行緒。
  • 併發數大時,要建立大量的執行緒,系統資源佔用大。
  • 連線建立之後,如果當前執行緒暫時沒有資料可讀,則執行緒就阻塞再Read上,造成執行緒資源浪費。

1.3、NIO

同步非阻塞模型,伺服器端用一個執行緒處理多個連線,客戶端傳送的連線請求會註冊到多路複用器上,多路複用器輪詢到連線有IO請求就進行處理:

NIO.png

NIO的非阻塞模式,使得一個執行緒從某通道傳送請求或者讀取資料時,如果目前沒有可用的資料,不會使執行緒阻塞,在資料可讀之前,該執行緒可以做其他的事情。

NIO有三大核心部分:

  • Channel(通道)
  • Buffer(緩衝區)
  • Selector(選擇器)

NIO-三大部件.png
由圖可知:

  • 每個Channel對應一個Buffer。
  • Selector對應一個執行緒,一個執行緒對應多個Channel。
  • Selector會根據不同的事件,在各個通道上切換。
  • Buffer是記憶體塊,底層是資料。

1.3.1、緩衝區(Buffer)

本質是可以讀寫資料的記憶體塊,Channel讀取或者寫入的資料必須通過Buffer:

Buffer.png

java.nio.Buffer抽象類的屬性:

// Invariants: mark <= position <= limit <= capacity
private int mark = -1; private int position = 0; private int limit; private int capacity; 複製程式碼

Buffer-屬性.png

1.3.2、通道(Channel)

通道是雙向的,可以讀操作、也可以寫操作。 java.nio.channels.Channel介面的常用實現類:

Channel.png

FileChannel用於檔案的資料讀寫,DatagramChannel用於UDP的資料讀寫,ServerSocketChannel和SocketChannel用於TCP的資料讀寫。

1.3.3、選擇器(Selector)

Selector選擇器使用一個執行緒來維護。多個Channel會以事件的方式註冊到同一個Selector,當有事件發生時,Selector會獲取事件,然後針對每個事件進行響應的處理。這樣就不必為每個連線建立一個執行緒,不用維護多執行緒,也不會有多執行緒之間的上下文切換導致的系統的開銷。 Selector示意圖:

Selector示意圖.png

1.4、AIO

非同步非阻塞模型,AIO引入非同步通道的概念,使用了Proactor,只有有效的請求才啟動執行緒,特點是先由作業系統完成後,才通知伺服器端程式啟動執行緒去處理,一般適用於連線數較多且連線時間較長的應用。

1.5、BIO NIO AIO 對比

對比.png

tencent.jpg