面試系列之IO模型

1.阻塞IO模型

最傳統(tǒng)的IO模型昨忆,就是在讀和寫(xiě)的過(guò)程中發(fā)生阻塞現(xiàn)象读规。
用戶(hù)線程發(fā)起IO請(qǐng)求之后抓督,內(nèi)核會(huì)去檢查數(shù)據(jù)是否已就緒。
如果未就緒束亏,內(nèi)核就會(huì)等待數(shù)據(jù)就緒铃在,用戶(hù)線程就會(huì)掛起,出讓CPU。
當(dāng)內(nèi)核數(shù)據(jù)就緒定铜,內(nèi)核就會(huì)將數(shù)據(jù)拷貝到用戶(hù)線程阳液,并喚醒用戶(hù)線程,解除阻塞狀態(tài)揣炕。
典型的阻塞 IO 模型的例子為:
data = socket.read();
如果數(shù)據(jù)沒(méi)有就緒帘皿,就會(huì)一直阻塞在 read 方法。

2.非阻塞 IO 模型

當(dāng)用戶(hù)線程發(fā)起一個(gè)read操作的時(shí)候畸陡,不會(huì)阻塞鹰溜,而是立馬得到一個(gè)結(jié)果。
如果結(jié)果是一個(gè)error丁恭,用戶(hù)線程就知道數(shù)據(jù)還沒(méi)準(zhǔn)備好曹动,又繼續(xù)請(qǐng)求read操作。
一旦數(shù)據(jù)就緒牲览,用戶(hù)線程又繼續(xù)發(fā)起read操作墓陈,內(nèi)核就會(huì)拷貝數(shù)據(jù)到用戶(hù)線程并返回。
也就數(shù)說(shuō)第献,非阻塞IO實(shí)際上是不斷的輪詢(xún)檢查數(shù)據(jù)是否準(zhǔn)備好贡必,而不會(huì)出讓CPU。
典型的非阻塞IO例子:

while(true){
    data = socket.read();
    if(data!= error){
      // 處理數(shù)據(jù)
     break;
   }
}

這種方式痊硕,不斷的輪詢(xún)檢查赊级,cpu占用率就非常高。

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

多路復(fù)用IO模型是目前用的比較多的IO模型岔绸,比如Redis就是用該模型理逊,java中的NIO也是用該模型。
多路復(fù)用IO模型就是有一個(gè)專(zhuān)門(mén)的線程負(fù)責(zé)管理所有的socket狀態(tài)盒揉,這個(gè)線程去輪詢(xún)多個(gè)socket的請(qǐng)求晋被,只有socket有真正的讀或?qū)懻?qǐng)求的時(shí)候,才會(huì)發(fā)起IO操作刚盈。
在多路復(fù)用IO模型中羡洛,只用一個(gè)線程來(lái)專(zhuān)門(mén)處理客戶(hù)端連接,所以不必像前兩種一樣藕漱,一旦有客戶(hù)端連接就新建一個(gè)線程欲侮,而且只有真正的客戶(hù)端讀寫(xiě)請(qǐng)求才會(huì)發(fā)起IO操作,這樣就大大減少了資源的使用和占用肋联。
在java nio中是用 selector.select()去查詢(xún)有沒(méi)有可可發(fā)起IO操作的通道威蕉,沒(méi)有的就阻塞,一旦有一個(gè)用戶(hù)線程有讀寫(xiě)請(qǐng)求橄仍,就對(duì)該線程發(fā)起IO操作韧涨。
多路復(fù)用IO模型也是通過(guò)輪詢(xún)的方式來(lái)檢查數(shù)據(jù)是否準(zhǔn)備牍戚,不過(guò)他只有一個(gè)線程而且是在內(nèi)核中輪詢(xún)檢查的,非阻塞IO是每個(gè)用戶(hù)線程各自輪詢(xún)檢查虑粥,顯然資源占用率低如孝,效率也會(huì)比較高。
要注意的是娩贷,多路復(fù)用IO畢竟還是用輪詢(xún)的方式第晰,一旦處理時(shí)間很長(zhǎng)或者響應(yīng)體很大響應(yīng)時(shí)間很長(zhǎng),就會(huì)影響排隊(duì)中的線程的等待時(shí)間彬祖。

4.信號(hào)驅(qū)動(dòng)IO模型

當(dāng)用戶(hù)線程發(fā)起一個(gè)io請(qǐng)求的時(shí)候但荤,會(huì)在socekt上注冊(cè)一個(gè)信號(hào)函數(shù),用戶(hù)線程會(huì)繼續(xù)執(zhí)行它的流程涧至,當(dāng)數(shù)據(jù)準(zhǔn)備就緒,內(nèi)核會(huì)發(fā)送一個(gè)信號(hào)給用戶(hù)線程桑包,用戶(hù)線程就會(huì)執(zhí)行信號(hào)函數(shù)中的邏輯來(lái)發(fā)起IO操作南蓬。

5.異步IO模型

用戶(hù)線程發(fā)起read操作的時(shí)候,立即去執(zhí)行其他業(yè)務(wù)哑了。內(nèi)核收到一個(gè)異步讀的請(qǐng)求之后赘方,就開(kāi)始等待數(shù)據(jù)準(zhǔn)備完成,數(shù)據(jù)準(zhǔn)備完成之后弱左,內(nèi)核會(huì)將數(shù)據(jù)拷貝到用戶(hù)線程窄陡,拷貝完之后在通知用戶(hù)線程數(shù)據(jù)已經(jīng)讀完。跟信號(hào)驅(qū)動(dòng)不同的是拆火,信號(hào)驅(qū)動(dòng)只是收到一個(gè)信號(hào)跳夭,再去用信號(hào)函數(shù)讀。異步IO是內(nèi)核直接給你们镜,在跟你說(shuō)好了币叹。

小結(jié)

阻塞IO:用戶(hù)線程阻塞掛起
非阻塞IO:用戶(hù)線程不阻塞了但是多個(gè)用戶(hù)線程一直占用CPU
多路復(fù)用IO:只有一個(gè)后臺(tái)線程占用cpu但是處理時(shí)間久的話(huà),其他用戶(hù)線程等待時(shí)間較長(zhǎng)
信號(hào)驅(qū)動(dòng)IO:線程可以立即去處理其他業(yè)務(wù)模狭,但是還需要通過(guò)信號(hào)函數(shù)來(lái)發(fā)起IO操作
異步IO:不需要信號(hào)函數(shù)發(fā)起IO操作了颈抚,而是內(nèi)核直接拷貝到用戶(hù)線程并通知

6.java io包

java io包

7.java nio包

java nio包

8.java nio主要內(nèi)容

傳統(tǒng)的io是基于字節(jié)流或字符流來(lái)操作的,而java nio是基于緩沖和通道來(lái)操作的嚼鹉。
java nio主要包括:channel(通道)贩汉、buffer(緩沖)、selector(選擇器)
也就是說(shuō)锚赤,數(shù)據(jù)都是從通道讀到緩存區(qū)匹舞,或者從緩存區(qū)寫(xiě)到通道,而選擇器監(jiān)聽(tīng)著多個(gè)通道的事件比如:鏈接打開(kāi)事件宴树,數(shù)據(jù)到達(dá)事件策菜,所以單個(gè)線程可以監(jiān)聽(tīng)多個(gè)通道。
另外,java io和java nio最大的區(qū)別就是又憨,io是面向流的翠霍,nio是面向緩沖的


java nio模型

Channel:channel和io中的stream差不多是一個(gè)級(jí)別的,只不過(guò)stream是單向的比如:InputStream(讀)蠢莺,OutputStream(寫(xiě))寒匙,而channel是雙向的既可以讀也可以寫(xiě)。
Buffer:buffer實(shí)際上就是一個(gè)容器躏将,底層是一個(gè)連續(xù)數(shù)組锄弱。channel從文件或網(wǎng)絡(luò)中讀到的數(shù)據(jù)必須先經(jīng)過(guò)buffer。


buffer

如上圖:客戶(hù)端發(fā)送請(qǐng)求先經(jīng)過(guò)buffer在統(tǒng)一到channel祸憋,服務(wù)端接受數(shù)據(jù)也是先經(jīng)過(guò)channel統(tǒng)一讀到buffer中在進(jìn)行處理会宪。
selector:selector是nio中核心的類(lèi),一個(gè)selector能夠注冊(cè)多個(gè)channel蚯窥,并且能夠檢測(cè)出多個(gè)channel的事件掸鹅,只有真正有讀寫(xiě)事件的時(shí)候才會(huì)發(fā)起io操作。這樣依賴(lài)只要用一個(gè)線程就能管理多個(gè)連接拦赠,避免線程的上下文切換巍沙,減少系統(tǒng)的開(kāi)銷(xiāo)。

9.nio中的緩存區(qū)

java io是面向字節(jié)或字符的荷鼠,意味著每次讀寫(xiě)都是一個(gè)字節(jié)或多個(gè)字節(jié)句携,頻繁的刷盤(pán),而且沒(méi)有緩存到一個(gè)地方也沒(méi)辦法前后移動(dòng)流的數(shù)據(jù)允乐。nio中的緩存區(qū)就是為了解決這些問(wèn)題矮嫉,每次讀寫(xiě)都將數(shù)據(jù)暫存到緩存區(qū)然后在批量刷盤(pán),而且還能夠自由的前后移動(dòng)讀取緩存中的數(shù)據(jù)牍疏,增加了數(shù)據(jù)處理的效率和靈活性敞临。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市麸澜,隨后出現(xiàn)的幾起案子挺尿,更是在濱河造成了極大的恐慌,老刑警劉巖炊邦,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件编矾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡馁害,警方通過(guò)查閱死者的電腦和手機(jī)窄俏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)碘菜,“玉大人凹蜈,你說(shuō)我怎么就攤上這事限寞。” “怎么了仰坦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵履植,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我悄晃,道長(zhǎng)玫霎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任妈橄,我火速辦了婚禮庶近,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘眷蚓。我一直安慰自己鼻种,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布沙热。 她就那樣靜靜地躺著普舆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪校读。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,549評(píng)論 1 312
  • 那天祖能,我揣著相機(jī)與錄音歉秫,去河邊找鬼。 笑死养铸,一個(gè)胖子當(dāng)著我的面吹牛雁芙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钞螟,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼兔甘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鳞滨?” 一聲冷哼從身側(cè)響起洞焙,我...
    開(kāi)封第一講書(shū)人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拯啦,沒(méi)想到半個(gè)月后澡匪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡褒链,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年唁情,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甫匹。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甸鸟,死狀恐怖惦费,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抢韭,我是刑警寧澤薪贫,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站篮绰,受9級(jí)特大地震影響后雷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吠各,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一臀突、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贾漏,春花似錦候学、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至伍掀,卻和暖如春掰茶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜜笤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工濒蒋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人把兔。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓沪伙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親县好。 傳聞我的和親對(duì)象是個(gè)殘疾皇子围橡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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