1. 程式人生 > >Java的中BIO、NIO、AIO-1

Java的中BIO、NIO、AIO-1

用戶 targe eee 技術 aio 下一步 caption page 情況下

Java的中BIO、NIO、AIO-1

java

最近在項目中用到TCP通信來完成命令和運行結果的交互,用的是典型的TCP通信中的C/S架構,原因很簡單:在業務需求低的環境下,這種架構簡單、穩定還容易寫。但是在實際部署的情況下,一直出現讀不到數據的空指針異常,按說BIO模式開發的應該阻塞直到有數據讀取,沒有找到原因就變通寫了一個消息隊列,使用定時器每1s從定時器中拿數據,解決了這個問題。但是想想這種同步阻塞的形式,就想了解一下其他的模式:NIO、AIO。好了,啰嗦了好多,進入正題:

IO操作的基本概念

在說明BIO/NIO/AIO之前,要先弄明白這些概念和原理,什麽是同步、異步,阻塞和非阻塞:

  • 同步
    在IO操作中,同步指的是用戶進程出發IO操作並等待或者輪詢的去查看IO操作是否就緒
  • 異步
    異步是指用戶進程在出發IO操作之後,便開始做自己的事情,IO操作由系統來完成,而當IO操作完成的時候,用戶進程會得到系統IO已經完成的通知。
  • 阻塞
    阻塞是指進程在訪問數據(讀寫操作)的時候,如果得不到數據就一直等待直到數據就緒,進行下一步的操作。
  • 非阻塞
    非阻塞是指進程在訪問數據(讀寫操作)的時候,進程會立即得到一個返回值,而不是一直等待下去。

總結起來同步異步是針對應用程序和內核的交互而言的,而阻塞和非阻塞是針對進程在訪問數據的時候,根據IO操作的就緒狀態來采取的不同方式,就是一種讀取和寫入操作實現方式。更底層一點來說,同步和異步只是跟IO操作過程中進程的狀態變化有關,而阻塞和非阻塞就是進程的兩種狀態。不要混淆了這些東西。

根據上面的基本概念,生成常見的四種IO模式:

  • 同步阻塞IO
  • 同步非阻塞IO
  • 異步阻塞IO
  • 異步非阻塞IO

下面來一一的說明這四種模型:

  • 同步阻塞IO
    同步阻塞IO是最簡單的IO模型,在此種方式下,用戶進程在發起一個IO操作以後,必須等待IO操作的完成,只有當真正完成了IO操作以後,用戶進程才能運行。JAVA傳統的IO模型屬於此種方式!

技術分享圖片
同步阻塞IO

  • 同步非阻塞IO
    在此種方式下,用戶進程發起一個IO操作以後,就可以返回做其他的事情,但是用戶進程需要時不時的去詢問IO操作是否就緒,這就需要用戶進程不斷的去輪詢、重復請求,這樣會消耗大量的cpu資源。一般情況下很少使用這種模型,而是在其他IO模型中使用非阻塞IO這一特性。

技術分享圖片
同步非阻塞

  • 異步阻塞IO
    這種模式是指一個應用發起一個IO操作之後,不等待內核IO操作的完成,等IO操作真正完成的時候,應用程序會得到IO操作完成的通知。這其實就是同步和異步的最關鍵區別,同步必須等待或者主動的去詢問IO操作是否完成,那為什麽說是阻塞呢?因為此時是通過select系統調用完成的,而select函數本身的實現方式是阻塞的,采用select函數有兩個好處就是它可以同時監聽多個文件句柄,從而提升系統的並發性。

技術分享圖片
nio

從上圖中可以看到,用戶首先將需要進行IO操作的socket添加到select中,然後阻塞等待select系統調用返回。當數據到達時,socket被激活,select函數返回。用戶線程正式發起read請求,讀取數據並繼續執行。使用select函數的優點並不僅限於此。雖然上述方式允許單線程內處理多個IO請求,但是每個IO請求的過程還是阻塞的(在select函數上阻塞),平均時間甚至比同步阻塞IO模型還要長。如果用戶線程只註冊自己感興趣的socket或者IO請求,然後去做自己的事情,等到數據到來時再進行處理,則可以提高CPU的利用率。

  • 異步非阻塞IO
    此種模式,用戶進程只需要發起一個IO操作然後立即返回,等IO操作真正的處理完成之後,應用程序會得到IO操作完成的通知,此時用戶只需要對數據進行處理就好了,不需要進行實際的IO讀寫操作,因為真正的IO讀寫操作已經由內核完成了。在IO多路復用模型中,事件循環將文件句柄的狀態事件通知給用戶線程,由用戶線程自行讀取數據、處理數據。而在異步IO模型中,當用戶線程收到通知時,數據已經被內核讀取完畢,並放在了用戶線程指定的緩沖區內,內核在IO完成後通知用戶線程直接使用即可。

技術分享圖片
aio

上面簡單的介紹了一下目前服務器編程中常見的幾種IO模型,但是真正把這幾種IO模型付諸實施的是幾種設計模式:

  • C/S模式,這是經典的BIO通信模型。
  • Reactor模式 是異步阻塞IO的處理模型
  • Proactor模式 是異步非阻塞IO的處理模型

第二篇說明詳細的說明這幾種模式!!

Java的中BIO、NIO、AIO-1