天天看點

Java BIO、NIO、AIO(NIO.2) 差別先來個例子了解一下概念,以銀行取款為例:Java對BIO、NIO、AIO的支援:BIO、NIO、AIO适用場景分析:一個IO操作其實分成了兩個步驟:發起IO請求和實際的IO操作。

轉自 http://stevex.blog.51cto.com/4300375/1284437

先來個例子了解一下概念,以銀行取款為例:

同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時,Java自己處理IO讀寫)。

異步 : 委托一小弟拿銀行卡到銀行取錢,然後給你(使用異步IO時,Java将IO讀寫委托給OS處理,需要将資料緩沖區位址和大小傳給OS(銀行卡和密碼),OS需要支援異步IO操作API)。

阻塞 : ATM排隊取款,你隻能等待(使用阻塞IO時,Java調用會一直阻塞到讀寫完成才傳回)。

非阻塞 : 櫃台取款,取個号,然後坐在椅子上做其它事,等号廣播會通知你辦理,沒到号你就不能去,你可以不斷問大堂經理排到了沒有,大堂經理如果說還沒到你就不能去(使用非阻塞IO時,如果不能讀寫Java調用會馬上傳回,當IO事件分發器會通知可讀寫時再繼續進行讀寫,不斷循環直到讀寫完成)。

Java對BIO、NIO、AIO的支援:

Java BIO : 同步并阻塞,伺服器實作模式為一個連接配接一個線程,即用戶端有連接配接請求時伺服器端就需要啟動一個線程進行處理,如果這個連接配接不做任何事情會造成不必要的線程開銷,當然可以通過線程池機制改善。

Java NIO : 同步非阻塞,伺服器實作模式為一個請求一個線程,即用戶端發送的連接配接請求都會注冊到多路複用器上,多路複用器輪詢到連接配接有I/O請求時才啟動一個線程進行處理。

Java AIO(NIO.2) : 異步非阻塞,伺服器實作模式為一個有效請求一個線程,用戶端的I/O請求都是由OS先完成了再通知伺服器應用去啟動線程進行處理,

BIO、NIO、AIO适用場景分析:

BIO方式适用于連接配接數目比較小且固定的架構,這種方式對伺服器資源要求比較高,并發局限于應用中,JDK1.4以前的唯一選擇,但程式直覺簡單易了解。

NIO方式适用于連接配接數目多且連接配接比較短(輕操作)的架構,比如聊天伺服器,并發局限于應用中,程式設計比較複雜,JDK1.4開始支援。

AIO方式使用于連接配接數目多且連接配接比較長(重操作)的架構,比如相冊伺服器,充分調用OS參與并發操作,程式設計比較複雜,JDK7開始支援。

另外,I/O屬于底層操作,需要作業系統支援,并發也需要作業系統的支援,是以性能方面不同作業系統差異會比較明顯。

一個IO操作其實分成了兩個步驟:發起IO請求和實際的IO操作。

同步IO和異步IO的差別就在于第二個步驟是否阻塞,如果實際的IO讀寫阻塞請求程序,那麼就是同步IO。

阻塞IO和非阻塞IO的差別在于第一步,發起IO請求是否會被阻塞,如果阻塞直到完成那麼就是傳統的阻塞IO,如果不阻塞,那麼就是非阻塞IO。

同步和異步是針對應用程式和核心的互動而言的,同步指的是使用者程序觸發IO操作并等待或者輪詢的去檢視IO操作是否就緒,而異步是指使用者程序觸發IO操作以後便開始做自己的事情,而當IO操作已經完成的時候會得到IO完成的通知。而阻塞和非阻塞是針對于程序在通路資料的時候,根據IO操作的就緒狀态來采取的不同方式,說白了是一種讀取或者寫入操作函數的實作方式,阻塞方式下讀取或者寫入函數将一直等待,而非阻塞方式下,讀取或者寫入函數會立即傳回一個狀态值。

是以,IO操作可以分為3類:同步阻塞(即早期的IO操作)、同步非阻塞(NIO)、異步(AIO)。

同步阻塞:在此種方式下,使用者程序在發起一個IO操作以後,必須等待IO操作的完成,隻有當真正完成了IO操作以後,使用者程序才能運作。JAVA傳統的IO模型屬于此種方式。

同步非阻塞:在此種方式下,使用者程序發起一個IO操作以後邊可傳回做其它事情,但是使用者程序需要時不時的詢問IO操作是否就緒,這就要求使用者程序不停的去詢問,進而引入不必要的CPU資源浪費。其中目前JAVA的NIO就屬于同步非阻塞IO。

異步:此種方式下是指應用發起一個IO操作以後,不等待核心IO操作的完成,等核心完成IO操作以後會通知應用程式。”