Blocking VS non-blocking IO

IO指Blocking IO

NIO指new/non-blocking IO

Blocking IO中降允,對于每一個連接,創(chuàng)建一個線程處理這個連接的IO事件激涤,連接和處理線程之間有1:1的關(guān)系拟糕。連接數(shù)受到JVM線程數(shù)的限制。JVM最大線程數(shù)限制參考http://jzhihui.iteye.com/blog/1271122倦踢,最大線程數(shù)由操作系統(tǒng)支持線程數(shù)送滞,java初始堆大小,最大堆大小以及每個線程棧大小決定辱挥。


NIO使用單個selector可處理多個連接犁嗅。


IO核心代碼

final Socket clientSocket = socket.accept();

new Thread(new Runnable() {

@Override

public void run() {

...

}

}).start();

服務(wù)端socket.accept()阻塞直至接受新的connection。

接受新的connection之后晤碘,建立新的線程褂微,處理這個連接,每一個連接都有一個線程處理园爷,連接數(shù)和線程數(shù)是1:1的關(guān)系宠蚂。客戶端并發(fā)的線程數(shù)由同時存活線程數(shù)決定童社。

NIO的基礎(chǔ)概念

NIO使用selector-based方法來處理網(wǎng)絡(luò)數(shù)據(jù)和事件(The NIO API uses a selector-based approach to handle network events and data)

ByteBuffer:數(shù)據(jù)容器(不影響原理的理解求厕,之后再講)。

NIO Selectors:Selector is a NIO component that determines if one or more channels are ready for reading and/or扰楼。

選擇器:選擇器是一個組件呀癣,這個組件可以決定此時是否有一個或多個的channels準備好進行讀寫。由于Selector可以處理多個連接弦赖,減輕了IO中的線程負擔项栏。

Channel: A channel represents a connection to an entity capable of performing IO operations such as a file or socket.

通道:通道是指連向可進行IO操作實體的連接。通道本質(zhì)上是特殊的連接蹬竖,特殊在其連接的對象都可進行IO操作沼沈。NIO的通道似乎都是雙向的。

Selector的使用币厕,需要5步

創(chuàng)建一個Selector庆冕,使得其它的Channel可以注冊到Selector

在注冊Channel時,要說明Selector對此Channel感興趣的時間

OP_ACCEPT:socket-accept operations的操作位

OP_CONNECT:socket-connect

OP_READ:read operation

OP_WRITE:write operation

調(diào)用Selector.select()阻塞劈榨,指導(dǎo)上述事件發(fā)生

事件發(fā)生之后访递,可以獲取到SelectionKey實例,每個實例都包括Channel的引用和實際發(fā)生的事件同辣。

此版本NIO核心代碼

serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {

try {

selector.select();

} catch (IOException ex) {

ex.printStackTrace();

// handle in a proper way

break;

}

Set readyKeys = selector.selectedKeys();

Iterator iterator = readyKeys.iterator();

while (iterator.hasNext()) {

SelectionKey key = (SelectionKey) iterator.next();

iterator.remove();

try {

if (key.isAcceptable()) {

ServerSocketChannel server = (ServerSocketChannel)

key.channel();

SocketChannel client = server.accept();

System.out.println("Accepted connection from " +

client);

client.configureBlocking(false);

client.register(selector, SelectionKey.OP_WRITE |

SelectionKey.OP_READ, ByteBuffer.allocate(100));

}

if (key.isReadable()) {

SocketChannel client = (SocketChannel) key.channel();

ByteBuffer output = (ByteBuffer) key.attachment();

client.read(output);

}

if (key.isWritable()) {

SocketChannel client = (SocketChannel) key.channel();

ByteBuffer output = (ByteBuffer) key.attachment();

output.flip();

client.write(output);

output.compact();

}

} catch (IOException ex) {

key.cancel();

try {

key.channel().close();

} catch (IOException cex) {

}

}

}

從代碼中可以看出此版本NIO需要開發(fā)者檢查網(wǎng)絡(luò)事件發(fā)生拷姿,同時觸發(fā)相應(yīng)的處理邏輯惭载。

NIO2

NIO允許分發(fā)IO操作,當IO操作完成時使用completion handler處理IO事件响巢。completion handler的執(zhí)行完全由底層系統(tǒng)決定描滔,對開發(fā)者隱藏。同時保證了每個channel同時

只有一個completion handler在執(zhí)行踪古。

NIO2核心代碼

channel.read(buffer, buffer,new EchoCompletionHandler(channel));

當讀取的IO完成之后含长,自動執(zhí)行Echo CompletionHandler的操作。

private final class EchoCompletionHandler implements

CompletionHandler {}

上述內(nèi)容講了

1. IO和NIO的本質(zhì)區(qū)別:IO的thread-per-connection的本質(zhì)以及NIO selector-based approch to handle network data and event.

2. IO實現(xiàn)伏穆,NIO1實現(xiàn)以及NIO2實現(xiàn)方式的區(qū)別拘泞,IO使用accept()阻塞等待連接發(fā)生之后,創(chuàng)建新的線程處理此連接枕扫;NIO1使用selector對channel進行監(jiān)聽陪腌,使用selector.select()阻塞直到某個channel準備好讀或?qū)懀枰_發(fā)者檢測事件的發(fā)生并提供相應(yīng)的處理邏輯烟瞧。NIO1是異步的诗鸭,selector可監(jiān)聽多個channel,這本質(zhì)上不同于IO参滴;NIO2同樣是基于selector但是NIO2的好處在于允許分發(fā)IO强岸,并且提供了complete handler用于在IO完成時,自動執(zhí)行砾赔,這種方法不需要檢測事件是否發(fā)生请唱,然后使用相應(yīng)的處理邏輯,這一切由底層實現(xiàn)过蹂。


參考:《netty in action》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聚至,隨后出現(xiàn)的幾起案子酷勺,更是在濱河造成了極大的恐慌,老刑警劉巖扳躬,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脆诉,死亡現(xiàn)場離奇詭異,居然都是意外死亡贷币,警方通過查閱死者的電腦和手機击胜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來役纹,“玉大人偶摔,你說我怎么就攤上這事〈俾觯” “怎么了辰斋?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵策州,是天一觀的道長。 經(jīng)常有香客問我宫仗,道長够挂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任藕夫,我火速辦了婚禮孽糖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘毅贮。我一直安慰自己办悟,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布嫩码。 她就那樣靜靜地躺著誉尖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铸题。 梳的紋絲不亂的頭發(fā)上铡恕,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音丢间,去河邊找鬼探熔。 笑死,一個胖子當著我的面吹牛烘挫,可吹牛的內(nèi)容都是我干的诀艰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饮六,長吁一口氣:“原來是場噩夢啊……” “哼其垄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卤橄,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绿满,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后窟扑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喇颁,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年嚎货,在試婚紗的時候發(fā)現(xiàn)自己被綠了橘霎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡殖属,死狀恐怖姐叁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤七蜘,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布谭溉,位于F島的核電站,受9級特大地震影響橡卤,放射性物質(zhì)發(fā)生泄漏扮念。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一碧库、第九天 我趴在偏房一處隱蔽的房頂上張望柜与。 院中可真熱鬧,春花似錦嵌灰、人聲如沸弄匕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迁匠。三九已至,卻和暖如春驹溃,著一層夾襖步出監(jiān)牢的瞬間城丧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工豌鹤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亡哄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓布疙,卻偏偏與公主長得像蚊惯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子灵临,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

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

  • 概述 NIO主要有三大核心部分:Channel(通道)截型,Buffer(緩沖區(qū)),Selector。 傳統(tǒng)IO基于...
    時之令閱讀 3,690評論 0 8
  • Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API儒溉,可以替代標準的Java I...
    JackChen1024閱讀 7,555評論 1 143
  • 前言: 之前的文章《Java文件IO常用歸納》主要寫了Java 標準IO要注意的細節(jié)和技巧宦焦,由于網(wǎng)上各種學習途徑,...
    androidjp閱讀 2,907評論 0 22
  • 轉(zhuǎn)自 http://www.ibm.com/developerworks/cn/education/java/j-...
    抓兔子的貓閱讀 2,309評論 0 22
  • java nio Java的IO體系:舊IO新IO:nio睁搭,用ByteBuffer和FileChannel讀寫ni...
    則不達閱讀 839評論 0 2