BIO與NIO废菱、AIO的區(qū)別

IO的方式通常分為幾種差油,同步阻塞的BIO、同步非阻塞的NIO憾筏、異步非阻塞的AIO嚎杨。

一、BIO

在JDK1.4出來之前氧腰,我們建立網(wǎng)絡(luò)連接的時候采用BIO模式磕潮,需要先在服務(wù)端啟動一個ServerSocket,然后在客戶端啟動Socket來對服務(wù)端進行通信容贝,默認情況下服務(wù)端需要對每個請求建立一堆線程等待請求自脯,而客戶端發(fā)送請求后,先咨詢服務(wù)端是否有線程相應(yīng)斤富,如果沒有則會一直等待或者遭到拒絕請求膏潮,如果有的話,客戶端會線程會等待請求結(jié)束后才繼續(xù)執(zhí)行满力。

二焕参、NIO

NIO本身是基于事件驅(qū)動思想來完成的轻纪,其主要想解決的是BIO的大并發(fā)問題: 在使用同步I/O的網(wǎng)絡(luò)應(yīng)用中,如果要同時處理多個客戶端請求叠纷,或是在客戶端要同時和多個服務(wù)器進行通訊刻帚,就必須使用多線程來處理。也就是說涩嚣,將每一個客戶端請求分配給一個線程來單獨處理崇众。這樣做雖然可以達到我們的要求,但同時又會帶來另外一個問題航厚。由于每創(chuàng)建一個線程顷歌,就要為這個線程分配一定的內(nèi)存空間(也叫工作存儲器),而且操作系統(tǒng)本身也對線程的總數(shù)有一定的限制幔睬。如果客戶端的請求過多眯漩,服務(wù)端程序可能會因為不堪重負而拒絕客戶端的請求,甚至服務(wù)器可能會因此而癱瘓麻顶。

NIO基于Reactor赦抖,當socket有流可讀或可寫入socket時,操作系統(tǒng)會相應(yīng)的通知引用程序進行處理辅肾,應(yīng)用再將流讀取到緩沖區(qū)或?qū)懭氩僮飨到y(tǒng)队萤。 也就是說,這個時候宛瞄,已經(jīng)不是一個連接就要對應(yīng)一個處理線程了浮禾,而是有效的請求交胚,對應(yīng)一個線程份汗,當連接沒有數(shù)據(jù)時,是沒有工作線程來處理的蝴簇。

BIO與NIO一個比較重要的不同杯活,是我們使用BIO的時候往往會引入多線程,每個連接一個單獨的線程熬词;而NIO則是使用單線程或者只使用少量的多線程旁钧,每個連接共用一個線程。

NIO的最重要的地方是當一個連接創(chuàng)建后互拾,不需要對應(yīng)一個線程歪今,這個連接會被注冊到多路復用器上面,所以所有的連接只需要一個線程就可以搞定颜矿,當這個線程中的多路復用器進行輪詢的時候寄猩,發(fā)現(xiàn)連接上有請求的話,才開啟一個線程進行處理骑疆,也就是一個請求一個線程模式田篇。

在NIO的處理方式中替废,當一個請求來的話,開啟線程進行處理泊柬,可能會等待后端應(yīng)用的資源(JDBC連接等)椎镣,其實這個線程就被阻塞了,當并發(fā)上來的話兽赁,還是會有BIO一樣的問題状答。

HTTP/1.1出現(xiàn)后,有了Http長連接闸氮,這樣除了超時和指明特定關(guān)閉的http header外剪况,這個鏈接是一直打開的狀態(tài)的,這樣在NIO處理中可以進一步的進化蒲跨,在后端資源中可以實現(xiàn)資源池或者隊列译断,當請求來的話,開啟的線程把請求和請求數(shù)據(jù)傳送給后端資源池或者隊列里面就返回或悲,并且在全局的地方保持住這個現(xiàn)場(哪個連接的哪個請求等)孙咪,這樣前面的線程還是可以去接受其他的請求,而后端的應(yīng)用的處理只需要執(zhí)行隊列里面的就可以了巡语,這樣請求處理和后端應(yīng)用是異步的.當后端處理完翎蹈,到全局地方得到現(xiàn)場,產(chǎn)生響應(yīng)男公,這個就實現(xiàn)了異步處理荤堪。

三、AIO

與NIO不同枢赔,當進行讀寫操作時澄阳,只須直接調(diào)用API的read或write方法即可。這兩種方法均為異步的踏拜,對于讀操作而言碎赢,當有流可讀取時,操作系統(tǒng)會將可讀的流傳入read方法的緩沖區(qū)速梗,并通知應(yīng)用程序肮塞;對于寫操作而言,當操作系統(tǒng)將write方法傳遞的流寫入完畢時姻锁,操作系統(tǒng)主動通知應(yīng)用程序枕赵。 即可以理解為,read/write方法都是異步的位隶,完成后會主動調(diào)用回調(diào)函數(shù)拷窜。 在JDK1.7中,這部分內(nèi)容被稱作NIO.2,主要在java.nio.channels包下增加了下面四個異步通道:

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousDatagramChannel

其中的read/write方法装黑,會返回一個帶回調(diào)函數(shù)的對象副瀑,當執(zhí)行完讀取/寫入操作后,直接調(diào)用回調(diào)函數(shù)恋谭。

BIO是一個連接一個線程糠睡。

NIO是一個請求一個線程。

AIO是一個有效請求一個線程疚颊。

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

  • 同步 : 自己親自出馬持銀行卡到銀行取錢(使用同步IO時,Java自己處理IO讀寫)材义;
  • 異步 : 委托一小弟拿銀行卡到銀行取錢均抽,然后給你(使用異步IO時,Java將IO讀寫委托給OS處理其掂,需要將數(shù)據(jù)緩沖區(qū)地址和大小傳給OS(銀行卡和密碼)油挥,OS需要支持異步IO操作API);
  • 阻塞 : ATM排隊取款款熬,你只能等待(使用阻塞IO時深寥,Java調(diào)用會一直阻塞到讀寫完成才返回);
  • 非阻塞 : 柜臺取款贤牛,取個號惋鹅,然后坐在椅子上做其它事,等號廣播會通知你辦理殉簸,沒到號你就不能去闰集,你可以不斷問大堂經(jīng)理排到了沒有,大堂經(jīng)理如果說還沒到你就不能去(使用非阻塞IO時般卑,如果不能讀寫Java調(diào)用會馬上返回武鲁,當IO事件分發(fā)器會通知可讀寫時再繼續(xù)進行讀寫,不斷循環(huán)直到讀寫完成)

Java對BIO椭微、NIO洞坑、AIO的支持:

  • Java BIO : 同步并阻塞盲链,服務(wù)器實現(xiàn)模式為一個連接一個線程蝇率,即客戶端有連接請求時服務(wù)器端就需要啟動一個線程進行處理,如果這個連接不做任何事情會造成不必要的線程開銷刽沾,當然可以通過線程池機制改善本慕。

  • Java NIO : 同步非阻塞,服務(wù)器實現(xiàn)模式為一個請求一個線程侧漓,即客戶端發(fā)送的連接請求都會注冊到多路復用器上锅尘,多路復用器輪詢到連接有I/O請求時才啟動一個線程進行處理。

  • Java AIO(NIO.2) : 異步非阻塞,服務(wù)器實現(xiàn)模式為一個有效請求一個線程藤违,客戶端的I/O請求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動線程進行處理浪腐,

BIO、NIO顿乒、AIO適用場景分析:

  • BIO方式適用于連接數(shù)目比較小且固定的架構(gòu)议街,這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中璧榄,JDK1.4以前的唯一選擇特漩,但程序直觀簡單易理解。

  • NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu)骨杂,比如聊天服務(wù)器涂身,并發(fā)局限于應(yīng)用中,編程比較復雜搓蚪,JDK1.4開始支持蛤售。

  • AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構(gòu),比如相冊服務(wù)器悍抑,充分調(diào)用OS參與并發(fā)操作搜骡,編程比較復雜,JDK7開始支持佑女。

另外记靡,I/O屬于底層操作,需要操作系統(tǒng)支持摸吠,并發(fā)也需要操作系統(tǒng)的支持嚎花,所以性能方面不同操作系統(tǒng)差異會比較明顯寸痢。

在高性能的I/O設(shè)計中,有兩個比較著名的模式Reactor和Proactor模式紊选,其中Reactor模式用于同步I/O啼止,而Proactor運用于異步I/O操作。

在比較這兩個模式之前献烦,我們首先的搞明白幾個概念,什么是阻塞和非阻塞巩那,什么是同步和異步,同步和異步是針對應(yīng)用程序和內(nèi)核的交互而言的,同步指的是用戶進程觸發(fā)IO操作并等待或者輪詢的去查看IO操作是否就緒即横,而異步是指用戶進程觸發(fā)IO操作以后便開始做自己的事情,而當IO操作已經(jīng)完成的時候會得到IO完成的通知东囚。而阻塞和非阻塞是針對于進程在訪問數(shù)據(jù)的時候,根據(jù)IO操作的就緒狀態(tài)來采取的不同方式舔庶,說白了是一種讀取或者寫入操作函數(shù)的實現(xiàn)方式,阻塞方式下讀取或者寫入函數(shù)將一直等待瞧甩,而非阻塞方式下弥鹦,讀取或者寫入函數(shù)會立即返回一個狀態(tài)值肚逸。

一般來說I/O模型可以分為:同步阻塞彬坏,同步非阻塞,異步阻塞栓始,異步非阻塞IO

同步阻塞IO:在此種方式下,用戶進程在發(fā)起一個IO操作以后禀忆,必須等待IO操作的完成落恼,只有當真正完成了IO操作以后,用戶進程才能運行佳谦。JAVA傳統(tǒng)的IO模型屬于此種方式!

同步非阻塞IO:在此種方式下钻蔑,用戶進程發(fā)起一個IO操作以后邊可返回做其它事情,但是用戶進程需要時不時的詢問IO操作是否就緒郑什,這就要求用戶進程不停的去詢問蒲肋,從而引入不必要的CPU資源浪費。其中目前JAVA的NIO就屬于同步非阻塞IO兜粘。

異步阻塞IO:此種方式下是指應(yīng)用發(fā)起一個IO操作以后,不等待內(nèi)核IO操作的完成孔轴,等內(nèi)核完成IO操作以后會通知應(yīng)用程序,這其實就是同步和異步最關(guān)鍵的區(qū)別路鹰,同步必須等待或者主動的去詢問IO是否完成,那么為什么說是阻塞的呢优构?因為此時是通過select系統(tǒng)調(diào)用來完成的雁竞,而select函數(shù)本身的實現(xiàn)方式是阻塞的钦椭,而采用select函數(shù)有個好處就是它可以同時監(jiān)聽多個文件句柄碑诉,從而提高系統(tǒng)的并發(fā)性!

異步非阻塞IO:在此種模式下德挣,用戶進程只需要發(fā)起一個IO操作然后立即返回,等IO操作真正的完成以后盲厌,應(yīng)用程序會得到IO操作完成的通知祸泪,此時用戶進程只需要對數(shù)據(jù)進行處理就好了,不需要進行實際的IO讀寫操作没隘,因為真正的IO讀取或者寫入操作已經(jīng)由內(nèi)核完成了。目前Java中還沒有支持此種IO模型阀湿。

轉(zhuǎn)載于:https://blog.csdn.net/skiof007/article/details/52873421

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瑰妄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子间坐,更是在濱河造成了極大的恐慌邑退,老刑警劉巖劳澄,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秒拔,居然都是意外死亡,警方通過查閱死者的電腦和手機作谚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門庵芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喳挑,你說我怎么就攤上這事∫了校” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵搂橙,是天一觀的道長笛坦。 經(jīng)常有香客問我,道長版扩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任蜻韭,我火速辦了婚禮柿扣,結(jié)果婚禮上肖方,老公的妹妹穿的比我還像新娘未状。我一直安慰自己,他們只是感情好司草,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著材泄,像睡著了一般吨岭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辣辫,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音姐浮,去河邊找鬼葬馋。 笑死卖鲤,一個胖子當著我的面吹牛畴嘶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播窗悯,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蒋院,長吁一口氣:“原來是場噩夢啊……” “哼亏钩!你這毒婦竟也來了欺旧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤彻坛,失蹤者是張志新(化名)和其女友劉穎踏枣,沒想到半個月后昌屉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茵瀑,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年竞帽,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屹篓。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡堆巧,死狀恐怖妄荔,靈堂內(nèi)的尸體忽然破棺而出谍肤,到底是詐尸還是另有隱情,我是刑警寧澤荒揣,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布系任,位于F島的核電站恳蹲,受9級特大地震影響俩滥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜举农,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望航背。 院中可真熱鬧棱貌,春花似錦玖媚、人聲如沸婚脱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篮洁。三九已至涩维,卻和暖如春袁波,著一層夾襖步出監(jiān)牢的瞬間蜗侈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工踏幻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留戳杀,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓吆倦,卻偏偏與公主長得像听诸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子桥嗤,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容