BIO NIO AIO

?IO的方式通常分為幾種,同步阻塞的BIO譬嚣、同步非阻塞的NIO耙蔑、異步非阻塞的AIO。

阻塞和非阻塞:是針對于進(jìn)程在訪問數(shù)據(jù)的時(shí)候孤荣,根據(jù)IO操作的就緒狀態(tài)來采取的不同方式甸陌,說白了是一種讀取或者寫入操作函數(shù)的實(shí)現(xiàn)方式

? ? ? ? ?阻塞方式下讀取或者寫入函數(shù)將一直等待,

????????非阻塞方式下盐股,讀取或者寫入函數(shù)會(huì)立即返回一個(gè)狀態(tài)值钱豁。

同步和異步: 是針對應(yīng)用程序和內(nèi)核的交互而言的

????????同步指的是用戶進(jìn)程觸發(fā)IO操作并等待或者輪詢的去查看IO操作是否就緒,

????????異步是指用戶進(jìn)程觸發(fā)IO操作以后便開始做自己的事情疯汁,而當(dāng)IO操作已經(jīng)完成的時(shí)候會(huì)得到IO完成的通知牲尺。

?一般來說I/O模型可以分為:同步阻塞,同步非阻塞幌蚊,異步阻塞谤碳,異步非阻塞IO

同步阻塞IO:在此種方式下,用戶進(jìn)程在發(fā)起一個(gè)IO操作以后溢豆,必須等待IO操作的完成蜒简,只有當(dāng)真正完成了IO操作以后,用戶進(jìn)程才能運(yùn)行漩仙。JAVA傳統(tǒng)的IO模型屬于此種方式搓茬!

同步非阻塞IO:?在此種方式下,用戶進(jìn)程發(fā)起一個(gè)IO操作以后邊可返回做其它事情队他,但是用戶進(jìn)程需要時(shí)不時(shí)的詢問IO操作是否就緒卷仑,這就要求用戶進(jìn)程不停的去詢問,從而引入不必要的CPU資源浪費(fèi)麸折。其中目前JAVA的NIO就屬于同步非阻塞IO锡凝。

異步阻塞IO:此種方式下是指應(yīng)用發(fā)起一個(gè)IO操作以后,不等待內(nèi)核IO操作的完成垢啼,等內(nèi)核完成IO操作以后會(huì)通知應(yīng)用程序窜锯,這其實(shí)就是同步和異步最關(guān)鍵的區(qū)別,同步必須等待或者主動(dòng)的去詢問IO是否完成膊夹,那么為什么說是阻塞的呢衬浑?因?yàn)榇藭r(shí)是通過select系統(tǒng)調(diào)用來完成的,而select函數(shù)本身的實(shí)現(xiàn)方式是阻塞的放刨,而采用select函數(shù)有個(gè)好處就是它可以同時(shí)監(jiān)聽多個(gè)文件句柄,從而提高系統(tǒng)的并發(fā)性尸饺!

?異步非阻塞IO: 在此種模式下进统,用戶進(jìn)程只需要發(fā)起一個(gè)IO操作然后立即返回助币,等IO操作真正的完成以后,應(yīng)用程序會(huì)得到IO操作完成的通知螟碎,此時(shí)用戶進(jìn)程只需要對數(shù)據(jù)進(jìn)行處理就好了眉菱,不需要進(jìn)行實(shí)際的IO讀寫操作,因?yàn)檎嬲腎O讀取或者寫入操作已經(jīng)由內(nèi)核完成了掉分。目前Java中還沒有支持此種IO模型俭缓。 ??

? ????????????????????????????????事件分離器

??????? 在IO讀寫時(shí),把 IO請求 與 讀寫操作 分離調(diào)配進(jìn)行酥郭,需要用到事件分離器华坦。根據(jù)處理機(jī)制的不同,事件分離器又分為:同步的Reactor和異步的Proactor不从。

??????? Reactor模型:

-應(yīng)用程序在事件分離器注冊 讀就緒事件 和 讀就緒事件處理器? ?

-事件分離器等待讀就緒事件發(fā)生? ??

-讀就緒事件發(fā)生惜姐,激活事件分離器,分離器調(diào)用 讀就緒事件處理器(即:可以進(jìn)行讀操作了椿息,開始讀)??

? - 讀事件處理器開始進(jìn)行讀操作歹袁,把讀到的數(shù)據(jù)提供給程序使用

??????? Proactor模型:

?- 應(yīng)用程序在事件分離器注冊 讀完成事件 和 讀完成事件處理器,并向操作系統(tǒng)發(fā)出異步讀請求

-?事件分離器等待操作系統(tǒng)完成讀取

-?在分離器等待過程中寝优,操作系統(tǒng)利用并行的內(nèi)核線程執(zhí)行實(shí)際的讀操作条舔,并將結(jié)果數(shù)據(jù)存入用戶自定義緩沖區(qū),最后通知事件分離器讀操作完成

-?事件分離器監(jiān)聽到 讀完成事件 后乏矾,激活 讀完成事件的處理器

-?讀完成事件處理器 處理用戶自定義緩沖區(qū)中的數(shù)據(jù)給應(yīng)用程序使用

?????? 同步和異步的區(qū)別就在于 讀 操作由誰完成:同步的Reactor是指程序發(fā)出讀請求后逞刷,由分離器監(jiān)聽到可以進(jìn)行讀操作時(shí)(需要獲得讀操作條件)通知事件處理器進(jìn)行讀操作,異步的Proactor是指程序發(fā)出讀請求后妻熊,操作系統(tǒng)立刻異步地進(jìn)行讀操作了夸浅,讀完之后在通知分離器,分離器激活處理器直接取用已讀到的數(shù)據(jù)扔役。

????????????????????????????????????????BIO

BIO即Blocking IO , 采用阻塞的方式實(shí)現(xiàn)帆喇。

也就是一個(gè)Socket套接字需要使用一個(gè)線程來進(jìn)行處理。發(fā)生建立鏈接亿胸,讀數(shù)據(jù)坯钦,寫數(shù)據(jù)的操作時(shí),都會(huì)有可能發(fā)生阻塞侈玄。

BIO的工作方式

????????????????????????????????????????NIO

NIO即New IO婉刀,?同步非阻塞。

NIO本身是基于事件驅(qū)動(dòng)思想來完成的序仙,其主要想解決的是BIO的大并發(fā)問題: 在使用同步I/O的網(wǎng)絡(luò)應(yīng)用中突颊,如果要同時(shí)處理多個(gè)客戶端請求,或是在客戶端要同時(shí)和多個(gè)服務(wù)器進(jìn)行通訊,就必須使用多線程來處理律秃。也就是說爬橡,將每一個(gè)客戶端請求分配給一個(gè)線程來單獨(dú)處理。

這樣做雖然可以達(dá)到我們的要求棒动,但同時(shí)又會(huì)帶來另外一個(gè)問題糙申。由于每創(chuàng)建一個(gè)線程,就要為這個(gè)線程分配一定的內(nèi)存空間(也叫工作存儲(chǔ)器)船惨,而且操作系統(tǒng)本身也對線程的總數(shù)有一定的限制柜裸。如果客戶端的請求過多,服務(wù)端程序可能會(huì)因?yàn)椴豢爸刎?fù)而拒絕客戶端的請求粱锐,甚至服務(wù)器可能會(huì)因此而癱瘓疙挺。

??? NIO基于Reactor,當(dāng)socket有流可讀或可寫入socket時(shí)卜范,操作系統(tǒng)會(huì)相應(yīng)的通知引用程序進(jìn)行處理衔统,應(yīng)用再將流讀取到緩沖區(qū)或?qū)懭氩僮飨到y(tǒng)。? 也就是說海雪,這個(gè)時(shí)候锦爵,已經(jīng)不是一個(gè)連接就要對應(yīng)一個(gè)處理線程了,而是有效的請求奥裸,對應(yīng)一個(gè)線程险掀,當(dāng)連接沒有數(shù)據(jù)時(shí),是沒有工作線程來處理的湾宙。

NIO的工作流程

NIO還提供了兩個(gè)新概念:Buffer和Channel

Buffer:

? ??????????– 是一塊連續(xù)的內(nèi)存塊樟氢。

? ??????????– 是 NIO 數(shù)據(jù)讀或?qū)懙闹修D(zhuǎn)地。

Channel:

? ??????????– 數(shù)據(jù)的源頭或者數(shù)據(jù)的目的地

? ??????????– 用于向buffer 提供數(shù)據(jù)或者讀取buffer 數(shù)據(jù) ,buffer 對象的唯一接口侠鳄。

? ??????????– 異步 I/O 支持

Buffer作為IO流中數(shù)據(jù)的緩沖區(qū)埠啃,而Channel則作為socket的IO流與Buffer的傳輸通道∥岸瘢客戶端socket與服務(wù)端socket之間的IO傳輸不直接把數(shù)據(jù)交給CPU使用碴开,

而是先經(jīng)過Channel通道把數(shù)據(jù)保存到Buffer,然后CPU直接從Buffer區(qū)讀寫數(shù)據(jù)博秫,一次可以讀寫更多的內(nèi)容潦牛。

使用Buffer提高IO效率的原因(這里與IO流里面的BufferedXXStream、BufferedReader挡育、BufferedWriter提高性能的原理一樣):IO的耗時(shí)主要花在數(shù)據(jù)傳輸?shù)穆飞习屯耄胀ǖ腎O是一個(gè)字節(jié)一個(gè)字節(jié)地傳輸,

而采用了Buffer的話即寒,通過Buffer封裝的方法(比如一次讀一行橡淆,則以行為單位傳輸而不是一個(gè)字節(jié)一次進(jìn)行傳輸)就可以實(shí)現(xiàn)“一大塊字節(jié)”的傳輸召噩。比如:IO就是送快遞,普通IO是一個(gè)快遞跑一趟明垢,采用了Buffer的IO就是一車跑一趟蚣常。很明顯市咽,buffer效率更高痊银,花在傳輸路上的時(shí)間大大縮短。

NIO和BIO的比較

?NIO的最重要的地方是當(dāng)一個(gè)連接創(chuàng)建后施绎,不需要對應(yīng)一個(gè)線程溯革,這個(gè)連接會(huì)被注冊到多路復(fù)用器上面,所以所有的連接只需要一個(gè)線程就可以搞定谷醉,當(dāng)這個(gè)線程中的多路復(fù)用器進(jìn)行輪詢的時(shí)候致稀,發(fā)現(xiàn)連接上有請求的話,才開啟一個(gè)線程進(jìn)行處理俱尼,也就是一個(gè)請求一個(gè)線程模式抖单。

在NIO的處理方式中,當(dāng)一個(gè)請求來的話遇八,開啟線程進(jìn)行處理矛绘,可能會(huì)等待后端應(yīng)用的資源(JDBC連接等),其實(shí)這個(gè)線程就被阻塞了刃永,當(dāng)并發(fā)上來的話货矮,還是會(huì)有BIO一樣的問題。

  HTTP/1.1出現(xiàn)后斯够,有了Http長連接囚玫,這樣除了超時(shí)和指明特定關(guān)閉的http header外,這個(gè)鏈接是一直打開的狀態(tài)的读规,這樣在NIO處理中可以進(jìn)一步的進(jìn)化抓督,在后端資源中可以實(shí)現(xiàn)資源池或者隊(duì)列,當(dāng)請求來的話束亏,開啟的線程把請求和請求數(shù)據(jù)傳送給后端資源池或者隊(duì)列里面就返回铃在,并且在全局的地方保持住這個(gè)現(xiàn)場(哪個(gè)連接的哪個(gè)請求等),這樣前面的線程還是可以去接受其他的請求枪汪,而后端的應(yīng)用的處理只需要執(zhí)行隊(duì)列里面的就可以了涌穆,這樣請求處理和后端應(yīng)用是異步的.當(dāng)后端處理完,到全局地方得到現(xiàn)場雀久,產(chǎn)生響應(yīng)宿稀,這個(gè)就實(shí)現(xiàn)了異步處理。

? ??????????????????????????????????????AIO

?在JDK1.7中赖捌,這部分內(nèi)容被稱作NIO.2祝沸,主要在java.nio.channels包下增加了下面四個(gè)異步通道:

AsynchronousSocketChannel

AsynchronousServerSocketChannel

AsynchronousFileChannel

AsynchronousDatagramChannel

其中的read/write方法矮烹,會(huì)返回一個(gè)帶回調(diào)函數(shù)的對象,當(dāng)執(zhí)行完讀取/寫入操作后罩锐,直接調(diào)用回調(diào)函數(shù)奉狈。

????????????????????????????????????????總結(jié)

Java對BIO、NIO涩惑、AIO的支持:

Java BIO : 同步并阻塞仁期,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理竭恬,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷跛蛋,當(dāng)然可以通過線程池機(jī)制改善。

Java NIO : 同步非阻塞痊硕,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請求一個(gè)線程赊级,即客戶端發(fā)送的連接請求都會(huì)注冊到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理岔绸。

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

BIO盒揉、NIO晋被、AIO適用場景分析:

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

NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu)翘县,比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中谴分,編程比較復(fù)雜锈麸,JDK1.4開始支持。

AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構(gòu)牺蹄,比如相冊服務(wù)器忘伞,充分調(diào)用OS參與并發(fā)操作展氓,編程比較復(fù)雜司忱,JDK7開始支持。

另外蜓肆,I/O屬于底層操作鼎天,需要操作系統(tǒng)支持舀奶,并發(fā)也需要操作系統(tǒng)的支持,所以性能方面不同操作系統(tǒng)差異會(huì)比較明顯斋射。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末育勺,一起剝皮案震驚了整個(gè)濱河市但荤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涧至,老刑警劉巖腹躁,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異南蓬,居然都是意外死亡纺非,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門蓖康,熙熙樓的掌柜王于貴愁眉苦臉地迎上來铐炫,“玉大人垒手,你說我怎么就攤上這事蒜焊。” “怎么了科贬?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵泳梆,是天一觀的道長。 經(jīng)常有香客問我榜掌,道長优妙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任憎账,我火速辦了婚禮套硼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胞皱。我一直安慰自己邪意,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布反砌。 她就那樣靜靜地躺著雾鬼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宴树。 梳的紋絲不亂的頭發(fā)上策菜,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機(jī)與錄音酒贬,去河邊找鬼又憨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锭吨,可吹牛的內(nèi)容都是我干的蠢莺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼耐齐,長吁一口氣:“原來是場噩夢啊……” “哼浪秘!你這毒婦竟也來了蒋情?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤耸携,失蹤者是張志新(化名)和其女友劉穎棵癣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夺衍,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狈谊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沟沙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片河劝。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖矛紫,靈堂內(nèi)的尸體忽然破棺而出赎瞎,到底是詐尸還是另有隱情,我是刑警寧澤颊咬,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布务甥,位于F島的核電站,受9級特大地震影響喳篇,放射性物質(zhì)發(fā)生泄漏敞临。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一麸澜、第九天 我趴在偏房一處隱蔽的房頂上張望挺尿。 院中可真熱鬧,春花似錦炊邦、人聲如沸编矾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洽沟。三九已至,卻和暖如春蜗细,著一層夾襖步出監(jiān)牢的瞬間裆操,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工炉媒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踪区,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓吊骤,卻偏偏與公主長得像缎岗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子白粉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

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

  • 歡迎訪問我的博客:http://wangnan.tech 參考http://qindongliang.iteye....
    GhostStories閱讀 1,405評論 1 27
  • 一溪椎、阻塞普舆?同步? 可能大家平常會(huì)經(jīng)常聽到這兩個(gè)名詞校读,但是沒花太多心思詳細(xì)了解沼侣,今天就來揭開這層面紗。 一次IO操作...
    叫我宮城大人閱讀 5,767評論 2 21
  • Java NIO(New IO)是從Java 1.4版本開始引入的一個(gè)新的IO API歉秫,可以替代標(biāo)準(zhǔn)的Java I...
    JackChen1024閱讀 7,555評論 1 143
  • 從三月份找實(shí)習(xí)到現(xiàn)在蛾洛,面了一些公司,掛了不少端考,但最終還是拿到小米雅潭、百度、阿里却特、京東、新浪筛圆、CVTE裂明、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,243評論 11 349
  • 我是日記星球239號星寶寶,來自深圳的水晶晶太援。我相信日積月累的力量闽晦,積跬步以致千里!這是我的第294篇日記提岔。 今天...
    水晶媽咪閱讀 358評論 0 0