程序員必知面試技術(shù)醋虏,編程面試IO模型有幾種评甜?分別是什么仔涩?

《Java網(wǎng)絡(luò)編程面試題》

出版單位:北京尚學(xué)堂優(yōu)效學(xué)院

優(yōu)效學(xué)院由清華大學(xué)著名的IT教育領(lǐng)導(dǎo)者馬士兵老師創(chuàng)辦,是一家線上線下相互融合的互聯(lián)網(wǎng)+培訓(xùn)機(jī)構(gòu)佩研。公司均由海外留學(xué)生和國內(nèi)行業(yè)精英人士擔(dān)任授課講師霞揉,主要成員均碩士且擁有十多年的行業(yè)經(jīng)驗(yàn)。畢業(yè)學(xué)生就職于國內(nèi)BAT以及海外著名公司绊序。優(yōu)效學(xué)院,名師執(zhí)教秽荞,高效學(xué)習(xí)骤公,成就未來。

著:張洋

11年工作經(jīng)驗(yàn) 曾就職聯(lián)眾游戲(程序員)扬跋、眾信旅游(Team Leader)阶捆、精智教育(聯(lián)合創(chuàng)始人)、中國石化(大數(shù)據(jù)高級顧問) 精通javaEE體系、互聯(lián)網(wǎng)產(chǎn)品架構(gòu)洒试,熟悉Sap Bw/HANA倍奢、多個(gè)大數(shù)據(jù)項(xiàng)目經(jīng)驗(yàn)

20180926版

IO模型有幾種?分別是什么垒棋?

在《Unix網(wǎng)絡(luò)編程》一書中提到了五種IO模型

分別是:阻塞IO、非阻塞IO捕犬、多路復(fù)用IO跷坝、信號驅(qū)動IO以及異步IO。

下面就分別來介紹一下這5種IO模型的異同碉碉。

1.阻塞IO模型

最傳統(tǒng)的一種IO模型柴钻,即在讀寫數(shù)據(jù)過程中會發(fā)生阻塞現(xiàn)象。

當(dāng)用戶線程發(fā)出IO請求之后垢粮,內(nèi)核會去查看數(shù)據(jù)是否就緒贴届,如果沒有就緒就會等待數(shù)據(jù)就緒,而用戶線程就會處于阻塞狀態(tài)蜡吧,用戶線程交出CPU毫蚓。當(dāng)數(shù)據(jù)就緒之后,內(nèi)核會將數(shù)據(jù)拷貝到用戶線程昔善,并返回結(jié)果給用戶線程元潘,用戶線程才解除block狀態(tài)。

典型的阻塞IO模型的例子為:

data = socket.openinputstream();

如果數(shù)據(jù)沒有就緒君仆,就會一直阻塞在read方法翩概。

阻塞IO模型

2.非阻塞IO模型

當(dāng)用戶線程發(fā)起一個(gè)read操作后,并不需要等待返咱,而是馬上就得到了一個(gè)結(jié)果钥庇。如果結(jié)果是一個(gè)error時(shí),它就知道數(shù)據(jù)還沒有準(zhǔn)備好咖摹,于是它可以再次發(fā)送read操作评姨。一旦內(nèi)核中的數(shù)據(jù)準(zhǔn)備好了,并且又再次收到了用戶線程的請求萤晴,那么它馬上就將數(shù)據(jù)拷貝到了用戶線程吐句,然后返回。

所以事實(shí)上店读,在非阻塞IO模型中蕴侧,用戶線程需要不斷地詢問內(nèi)核數(shù)據(jù)是否就緒,也就說非阻塞IO不會交出CPU两入,而會一直占用CPU净宵。

典型的非阻塞IO模型一般如下:

偽代碼

while(true){

new MyThread(socket)

}

class MyThread{

data = socket.read();

if(data!= error){

處理數(shù)據(jù)

break;

}

但是對于非阻塞IO就有一個(gè)非常嚴(yán)重的問題,在while循環(huán)中需要不斷地去詢問內(nèi)核數(shù)據(jù)是否就緒,這樣會導(dǎo)致CPU占用率非常高择葡,因此一般情況下很少使用while循環(huán)這種方式來讀取數(shù)據(jù)紧武。

非阻塞IO模型

3.多路復(fù)用IO模型

多路復(fù)用IO模型是目前使用得比較多的模型。Java NIO實(shí)際上就是多路復(fù)用IO敏储。

在多路復(fù)用IO模型中阻星,會有一個(gè)線程不斷去輪詢多個(gè)socket的狀態(tài),只有當(dāng)socket真正有讀寫事件時(shí)已添,才真正調(diào)用實(shí)際的IO讀寫操作妥箕。因?yàn)樵诙嗦窂?fù)用IO模型中,只需要使用一個(gè)線程就可以管理多個(gè)socket更舞,系統(tǒng)不需要建立新的進(jìn)程或者線程畦幢,也不必維護(hù)這些線程和進(jìn)程,并且只有在真正有socket讀寫事件進(jìn)行時(shí)缆蝉,才會使用IO資源宇葱,所以它大大減少了資源占用。

在Java NIO中刊头,是通過selector.select()去查詢每個(gè)通道是否有到達(dá)事件黍瞧,如果沒有事件,則一直阻塞在那里原杂,因此這種方式會導(dǎo)致用戶線程的阻塞印颤。

也許有朋友會說,我可以采用 多線程+ 阻塞IO 達(dá)到類似的效果穿肄,但是由于在多線程 + 阻塞IO 中年局,每個(gè)socket對應(yīng)一個(gè)線程,這樣會造成很大的資源占用被碗,并且尤其是對于長連接來說某宪,線程的資源一直不會釋放仿村,如果后面陸續(xù)有很多連接的話锐朴,就會造成性能上的瓶頸。

而多路復(fù)用IO模式蔼囊,通過一個(gè)線程就可以管理多個(gè)socket焚志,只有當(dāng)socket真正有讀寫事件發(fā)生才會占用資源來進(jìn)行實(shí)際的讀寫操作。因此畏鼓,多路復(fù)用IO比較適合連接數(shù)比較多的情況酱酬。

另外多路復(fù)用IO為何比非阻塞IO模型的效率高是因?yàn)樵诜亲枞鸌O中,不斷地詢問socket狀態(tài)時(shí)通過用戶線程去進(jìn)行的云矫,而在多路復(fù)用IO中膳沽,輪詢每個(gè)socket狀態(tài)是內(nèi)核在進(jìn)行的,這個(gè)效率要比用戶線程要高的多。

不過要注意的是挑社,多路復(fù)用IO模型是通過輪詢的方式來檢測是否有事件到達(dá)陨界,并且對到達(dá)的事件逐一進(jìn)行響應(yīng)。因此對于多路復(fù)用IO模型來說痛阻,一旦事件響應(yīng)體很大菌瘪,那么就會導(dǎo)致后續(xù)的事件遲遲得不到處理,并且會影響新的事件輪詢阱当。

多路復(fù)用IO模型

4.信號驅(qū)動IO模型

在信號驅(qū)動IO模型中俏扩,當(dāng)用戶線程發(fā)起一個(gè)IO請求操作,會給對應(yīng)的socket注冊一個(gè)信號函數(shù)弊添,然后用戶線程會繼續(xù)執(zhí)行录淡,當(dāng)內(nèi)核數(shù)據(jù)就緒時(shí)會發(fā)送一個(gè)信號給用戶線程,用戶線程接收到信號之后表箭,便在信號函數(shù)中調(diào)用IO讀寫操作來進(jìn)行實(shí)際的IO請求操作赁咙。

信號驅(qū)動IO模型

5.異步IO模型

異步IO模型才是最理想的IO模型,在異步IO模型中免钻,當(dāng)用戶線程發(fā)起read操作之后彼水,立刻就可以開始去做其它的事。

而另一方面极舔,從內(nèi)核的角度凤覆,當(dāng)它受到一個(gè)asynchronous read之后,它會立刻返回拆魏,說明read請求已經(jīng)成功發(fā)起了盯桦,因此不會對用戶線程產(chǎn)生任何block。

然后渤刃,內(nèi)核會等待數(shù)據(jù)準(zhǔn)備完成拥峦,然后將數(shù)據(jù)拷貝到用戶線程,當(dāng)這一切都完成之后卖子,內(nèi)核會給用戶線程發(fā)送一個(gè)信號略号,告訴它read操作完成了。

也就說用戶線程完全不需要實(shí)際的整個(gè)IO操作是如何進(jìn)行的洋闽,只需要先發(fā)起一個(gè)請求玄柠,當(dāng)接收內(nèi)核返回的成功信號時(shí)表示IO操作已經(jīng)完成,可以直接去使用數(shù)據(jù)了诫舅。

也就說在異步IO模型中羽利,IO操作的兩個(gè)階段都不會阻塞用戶線程,這兩個(gè)階段都是由內(nèi)核自動完成刊懈,然后發(fā)送一個(gè)信號告知用戶線程操作已完成这弧。

用戶線程中不需要再次調(diào)用IO函數(shù)進(jìn)行具體的讀寫娃闲。

這點(diǎn)是和信號驅(qū)動模型有所不同的

在信號驅(qū)動模型中,當(dāng)用戶線程接收到信號表示數(shù)據(jù)已經(jīng)就緒匾浪,然后需要用戶線程調(diào)用IO函數(shù)進(jìn)行實(shí)際的讀寫操作畜吊;而在異步IO模型中,收到信號表示IO操作已經(jīng)完成户矢,不需要再在用戶線程中調(diào)用iO函數(shù)進(jìn)行實(shí)際的讀寫操作玲献。

注意,異步IO是需要操作系統(tǒng)的底層支持梯浪,在Java 7中捌年,提供了Asynchronous IO。也就是java中的AIO NIO2.0

異步IO模型

前面四種IO模型實(shí)際上都屬于同步IO挂洛,只有最后一種是真正的異步IO礼预,因?yàn)闊o論是多路復(fù)用IO還是信號驅(qū)動模型,IO操作的第2個(gè)階段都會引起用戶線程阻塞虏劲,也就是內(nèi)核進(jìn)行數(shù)據(jù)拷貝的過程都會讓用戶線程阻塞托酸。

本文章為連載內(nèi)容,大家可以持續(xù)關(guān)注小編柒巫,我將盡其所能的為大家提供技術(shù)性實(shí)踐資料励堡、文章、視頻堡掏。

感謝大家的支持应结!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泉唁,隨后出現(xiàn)的幾起案子鹅龄,更是在濱河造成了極大的恐慌,老刑警劉巖亭畜,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扮休,死亡現(xiàn)場離奇詭異,居然都是意外死亡拴鸵,警方通過查閱死者的電腦和手機(jī)玷坠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宝踪,“玉大人侨糟,你說我怎么就攤上這事碍扔〈裨铮” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵不同,是天一觀的道長厉膀。 經(jīng)常有香客問我溶耘,道長,這世上最難降的妖魔是什么服鹅? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任凳兵,我火速辦了婚禮,結(jié)果婚禮上企软,老公的妹妹穿的比我還像新娘庐扫。我一直安慰自己,他們只是感情好仗哨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布形庭。 她就那樣靜靜地躺著,像睡著了一般厌漂。 火紅的嫁衣襯著肌膚如雪萨醒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天苇倡,我揣著相機(jī)與錄音富纸,去河邊找鬼。 笑死旨椒,一個(gè)胖子當(dāng)著我的面吹牛晓褪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播综慎,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼辞州,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寥粹?” 一聲冷哼從身側(cè)響起变过,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涝涤,沒想到半個(gè)月后媚狰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阔拳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年崭孤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糊肠。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辨宠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出货裹,到底是詐尸還是另有隱情嗤形,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布弧圆,位于F島的核電站赋兵,受9級特大地震影響笔咽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜霹期,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一叶组、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧历造,春花似錦甩十、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至垮刹,卻和暖如春达吞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荒典。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工酪劫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寺董。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓覆糟,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遮咖。 傳聞我的和親對象是個(gè)殘疾皇子滩字,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

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