真正理解NIO

前言

高并發(fā)量引起的問題

一個使用傳統(tǒng)阻塞I/O的系統(tǒng),如果還是使用傳統(tǒng)的一個請求對應一個線程這種模式,一旦有高并發(fā)的大量請求,就會有如下問題:?

1、線程不夠用, 就算使用了線程池復用線程也無濟于事;?

2筹陵、阻塞I/O模式下,會有大量的線程被阻塞,一直在等待數(shù)據(jù),這個時候的線程被掛起,只能干等,CPU利用率很低,換句話說,系統(tǒng)的吞吐量差;?

3刽锤、如果網(wǎng)絡I/O堵塞或者有網(wǎng)絡抖動或者網(wǎng)絡故障等,線程的阻塞時間可能很長。整個系統(tǒng)也變的不可靠;

什么是NIO

java.nio全稱java non-blocking IO(實際上是 new io)朦佩,是指JDK 1.4 及以上版本里提供的新api(New IO) 并思,為所有的原始類型(boolean類型除外)提供緩存支持的數(shù)據(jù)容器,使用它可以提供非阻塞式的高伸縮性網(wǎng)絡语稠。

HTTP2.0使用了多路復用的技術宋彼,做到同一個連接并發(fā)處理多個請求,而且并發(fā)請求的數(shù)量比HTTP1.1大了好幾個數(shù)量級仙畦。

IO和NIO的區(qū)別

原有的 IO 是面向流的输涕、阻塞的,NIO 則是面向塊的慨畸、非阻塞的莱坎。

怎么理解IO是面向流的、阻塞的

java1.4以前的io模型寸士,一連接對一個線程檐什。

原始的IO是面向流的,不存在緩存的概念碉京。Java IO面向流意味著每次從流中讀一個或多個字節(jié)厢汹,直至讀取所有字節(jié),它們沒有被緩存在任何地方谐宙。此外,它不能前后移動流中的數(shù)據(jù)界弧。如果需要前后移動從流中讀取的數(shù)據(jù)凡蜻,需要先將它緩存到一個緩沖區(qū)

Java IO的各種流是阻塞的,這意味著當一個線程調用read或 write方法時垢箕,該線程被阻塞划栓,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入条获,該線程在此期間不能再干任何事情了忠荞。

阻塞I/O模型

怎么理解NIO是面向塊的、非阻塞的

NIO是面向緩沖區(qū)的。數(shù)據(jù)讀取到一個它稍后處理的緩沖區(qū)委煤,需要時可在緩沖區(qū)中前后移動堂油,這就增加了處理過程中的靈活性。

Java NIO的非阻塞模式碧绞,使一個線程從某通道發(fā)送請求讀取數(shù)據(jù)府框,但是它僅能得到目前可用的數(shù)據(jù),如果目前沒有數(shù)據(jù)可用時讥邻,就什么都不會獲取迫靖,而不是保持線程阻塞,所以直至數(shù)據(jù)變的可以讀取之前兴使,該線程可以繼續(xù)做其他的事情系宜。 非阻塞寫也是如此,一個線程請求寫入一些數(shù)據(jù)到某通道发魄,但不需要等待它完全寫入盹牧,這個線程同時可以去做別的事情。

通俗理解:NIO是可以做到用一個線程來處理多個操作的欠母。假設有10000個請求過來,根據(jù)實際情況欢策,可以分配50或者100個線程來處理。不像之前的阻塞IO那樣赏淌,非得分配10000個踩寇。

NIO的核心實現(xiàn)

在標準IO API中,你可以操作字節(jié)流和字符流六水,但在新IO中俺孙,你可以操作通道和緩沖,數(shù)據(jù)總是從通道被讀取到緩沖中或者從緩沖寫入到通道中掷贾。

NIO核心API Channel, Buffer, Selector

通道Channel

NIO的通道類似于流睛榄,但有些區(qū)別如下:

1. 通道可以同時進行讀寫,而流只能讀或者只能寫

2. 通道可以實現(xiàn)異步讀寫數(shù)據(jù)

3. 通道可以從緩沖讀數(shù)據(jù)想帅,也可以寫數(shù)據(jù)到緩沖:?

可以從通道讀取數(shù)據(jù)到緩沖區(qū)场靴,也可以把緩沖區(qū)的數(shù)據(jù)寫到通道中

緩存Buffer

緩沖區(qū)本質上是一個可以寫入數(shù)據(jù)的內存塊,然后可以再次讀取港准,該對象提供了一組方法旨剥,可以更輕松地使用內存塊,使用緩沖區(qū)讀取和寫入數(shù)據(jù)通常遵循以下四個步驟:

1. 寫數(shù)據(jù)到緩沖區(qū)浅缸;

2. 調用buffer.flip()方法轨帜;

3. 從緩沖區(qū)中讀取數(shù)據(jù);

4. 調用buffer.clear()或buffer.compat()方法衩椒;

當向buffer寫入數(shù)據(jù)時蚌父,buffer會記錄下寫了多少數(shù)據(jù)哮兰,一旦要讀取數(shù)據(jù),需要通過flip()方法將Buffer從寫模式切換到讀模式苟弛,在讀模式下可以讀取之前寫入到buffer的所有數(shù)據(jù)喝滞,一旦讀完了所有的數(shù)據(jù),就需要清空緩沖區(qū)嗡午,讓它可以再次被寫入囤躁。

Buffer在與Channel交互時,需要一些標志:

buffer的大小/容量 -?Capacity

作為一個內存塊荔睹,Buffer有一個固定的大小值狸演,用參數(shù)capacity表示。

當前讀/寫的位置 -?Position?

當寫數(shù)據(jù)到緩沖時僻他,position表示當前待寫入的位置宵距,position最大可為capacity – 1;當從緩沖讀取數(shù)據(jù)時吨拗,position表示從當前位置讀取满哪。

信息末尾的位置 -?limit

在寫模式下,緩沖區(qū)的limit表示你最多能往Buffer里寫多少數(shù)據(jù)劝篷; 寫模式下哨鸭,limit等于Buffer的capacity,意味著你還能從緩沖區(qū)獲取多少數(shù)據(jù)娇妓。

下圖展示了buffer中三個關鍵屬性capacity像鸡,position以及l(fā)imit在讀寫模式中的說明:

buffer中三個關鍵屬性capacity,position以及l(fā)imit在讀寫模式中的說明

緩沖區(qū)常用的操作

向緩沖區(qū)寫數(shù)據(jù):

? ? 1. 從Channel寫到Buffer哈恰;

? ? 2. 通過Buffer的put方法寫到Buffer中只估;

從緩沖區(qū)讀取數(shù)據(jù):

? ? 1. 從Buffer中讀取數(shù)據(jù)到Channel;

? ? 2. 通過Buffer的get方法從Buffer中讀取數(shù)據(jù)着绷;

flip方法:

? ? ?將Buffer從寫模式切換到讀模式蛔钙,將position值重置為0,limit的值設置為之前position的值荠医;

clear方法 vs compact方法:

? ? ? ?clear方法清空緩沖區(qū)吁脱;compact方法只會清空已讀取的數(shù)據(jù),而還未讀取的數(shù)據(jù)繼續(xù)保存在Buffer中彬向;

Selector

一個組件豫喧,可以檢測多個NIO channel,看看讀或者寫事件是否就緒幢泼。

多個Channel以事件的方式可以注冊到同一個Selector,從而達到用一個線程處理多個請求成為可能讲衫。

一個thread對應多個channel,一個channel處理一個請求缕棵。
當你調用Selector的select()或者?selectNow()?方法它只會返回有數(shù)據(jù)讀取的SelectableChannel的實例.

Thanks for:

學習NIO

美團wiki-NIO

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末孵班,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子招驴,更是在濱河造成了極大的恐慌篙程,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件别厘,死亡現(xiàn)場離奇詭異虱饿,居然都是意外死亡,警方通過查閱死者的電腦和手機触趴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門氮发,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冗懦,你說我怎么就攤上這事爽冕。” “怎么了披蕉?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵颈畸,是天一觀的道長。 經(jīng)常有香客問我没讲,道長眯娱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任爬凑,我火速辦了婚禮徙缴,結果婚禮上,老公的妹妹穿的比我還像新娘贰谣。我一直安慰自己娜搂,他們只是感情好,可當我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布吱抚。 她就那樣靜靜地躺著百宇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秘豹。 梳的紋絲不亂的頭發(fā)上携御,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機與錄音既绕,去河邊找鬼啄刹。 笑死,一個胖子當著我的面吹牛凄贩,可吹牛的內容都是我干的誓军。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼疲扎,長吁一口氣:“原來是場噩夢啊……” “哼昵时!你這毒婦竟也來了捷雕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤壹甥,失蹤者是張志新(化名)和其女友劉穎救巷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體句柠,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡浦译,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了溯职。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片精盅。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缸榄,靈堂內的尸體忽然破棺而出渤弛,到底是詐尸還是另有隱情,我是刑警寧澤甚带,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布她肯,位于F島的核電站,受9級特大地震影響鹰贵,放射性物質發(fā)生泄漏晴氨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一碉输、第九天 我趴在偏房一處隱蔽的房頂上張望籽前。 院中可真熱鬧,春花似錦敷钾、人聲如沸枝哄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挠锥。三九已至,卻和暖如春侨赡,著一層夾襖步出監(jiān)牢的瞬間蓖租,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工羊壹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蓖宦,地道東北人。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓油猫,卻偏偏與公主長得像稠茂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子情妖,可洞房花燭夜當晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內容