深刻了解Netty【一】BIO、NIO、AIO簡單介紹

引言

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

1.一、使用場景

  • BIO

BIO適用於鏈接數比較小的應用,這種IO模型對服務器資源要求比較高。服務器

  • NIO

NIO適用於鏈接數目多、鏈接時間短的應用,好比聊天、彈幕、服務器間通信等應用。多線程

  • AIO

AIO適用於鏈接數目多、鏈接時間長的應用,好比相冊服務器。併發

1.二、BIO

同步並阻塞模型,服務器會爲每個鏈接創建一個線程,若是鏈接過多,且線程不作任何事情,會極大的浪費資源,示意圖以下:
BIO.png異步

1.2.一、機制

BIO-工做機制.png
流程:性能

  1. 服務器端啓動ServerSocket。
  2. 客戶端啓動Socket對服務器進行通訊,服務器會爲每一個客戶端創建一個線程與之通訊。
  3. 客戶端發送請求,先諮詢服務器是否有線程響應,若是沒有則會等待,或者被拒絕。
  4. 若是有響應,客戶端線程會等待請求結束後,再繼續執行。

1.2.二、問題

  • 服務端對於每一個請求都要創建獨立的線程。
  • 併發數大時,要建立大量的線程,系統資源佔用大。
  • 鏈接創建以後,若是當前線程暫時沒有數據可讀,則線程就阻塞再Read上,形成線程資源浪費。

1.三、NIO

同步非阻塞模型,服務器端用一個線程處理多個鏈接,客戶端發送的鏈接請求會註冊到多路複用器上,多路複用器輪詢到鏈接有IO請求就進行處理:
NIO.pngspa

NIO的非阻塞模式,使得一個線程從某通道發送請求或者讀取數據時,若是目前沒有可用的數據,不會使線程阻塞,在數據可讀以前,該線程能夠作其餘的事情。操作系統

NIO有三大核心部分:線程

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

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

  • 每一個Channel對應一個Buffer。
  • Selector對應一個線程,一個線程對應多個Channel。
  • Selector會根據不一樣的事件,在各個通道上切換。
  • Buffer是內存塊,底層是數據。

1.3.一、緩衝區(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.二、通道(Channel)

通道是雙向的,能夠讀操做、也能夠寫操做。
java.nio.channels.Channel接口的經常使用實現類:
Channel.png

FileChannel用於文件的數據讀寫,DatagramChannel用於UDP的數據讀寫,ServerSocketChannel和SocketChannel用於TCP的數據讀寫。

1.3.三、選擇器(Selector)

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

Selector示意圖.png

1.四、AIO

異步非阻塞模型,AIO引入異步通道的概念,使用了Proactor,只有有效的請求才啓動線程,特色是先由操做系統完成後,才通知服務器端程序啓動線程去處理,通常適用於鏈接數較多且鏈接時間較長的應用。

1.五、BIO NIO AIO 對比

對比.png

tencent.jpg

相關文章
相關標籤/搜索