JAVA過關(guān)題-NIO是什么?適用于何種場景

文1轉(zhuǎn)自:http://blog.csdn.net/jiyiqinlovexx/article/details/51204726
文2轉(zhuǎn)自:http://www.php.cn/java-article-361228.html
侵刪

文1

引言

BIO(Blocking-IO)和NIO(Non-Blocking-IO或New IO)是兩種不同的網(wǎng)絡(luò)通信模型,現(xiàn)如今NIO已經(jīng)大量應(yīng)用在Jetty、ZooKeeper、Netty等開源框架中。

一個面向流、一個面向緩沖區(qū)

一個是阻塞式的、一個非阻塞

一個沒有io多路復(fù)用器、一個有

下面通過一個例子解釋兩者區(qū)別:

假設(shè)當(dāng)前服務(wù)端程序需要同時從與多個客戶端建立的連接讀取數(shù)據(jù)。

使用BIO

如果采用阻塞式IO,單線程情況下,處理者線程可能阻塞在其中一個套接字的read上,導(dǎo)致另一個套接字即使準(zhǔn)備好了數(shù)據(jù)也無法處理,這個時候解決的方法就是針對每一個套接字,都新建一個線程處理其數(shù)據(jù)讀取。

所以說,在BIO工作模式下,服務(wù)端程序要想同時處理多個套接字的數(shù)據(jù)讀取,在等待接收連接請求的主線程之外,還要為每一個建立好的連接分配一個新的線程進行處理。

使用NIO

輪詢方式

如果將套接字讀操作換成非阻塞的,那么只需要一個線程就可以同時處理套接字,每次檢查一個套接字,有數(shù)據(jù)則讀取,沒有則檢查下一個,因為是非阻塞的,所以執(zhí)行read操作時若沒有數(shù)據(jù)準(zhǔn)備好則立即返回,不會發(fā)生阻塞。

I/O多路復(fù)用

這種輪詢的方式缺點是浪費CPU資源,大部分時間可能都是無數(shù)據(jù)可讀的,不必仍不間斷的反復(fù)執(zhí)行read操作,I/O多路復(fù)用(IOmultiplexing)是一種更好的方法,調(diào)用select函數(shù)時,其內(nèi)部會維護一張監(jiān)聽的套接字的列表,其會一直阻塞直到其中某一個套接字有數(shù)據(jù)準(zhǔn)備好才返回,并告訴是哪個套接字可讀,這時再調(diào)用該套接字的read函數(shù)效率更高。

所以基本可以認(rèn)為 “NIO = I/O多路復(fù)用 + 非阻塞式I/O”,大部分情況下是單線程,但也有超過一個線程實現(xiàn)NIO的情況

NIO三種模型

上面所講到的只需要一個線程就可以同時處理多個套接字,這只是其中的一種單線程模型,是一種較為極端的情況,NIO主要包含三種線程模型:

  1. Reactor單線程模型

  2. Reactor多線程模型

3)主從Reactor多線程模型

Reactor單線程模型:

單個線程完成所有事情包括接收客戶端的TCP連接請求,讀取和寫入套接字?jǐn)?shù)據(jù)等。

對于一些小容量應(yīng)用場景,可以使用單線程模型。但是對于高負(fù)載、大并發(fā)的應(yīng)用卻不合適,主要原因如下:

  1. 一個NIO線程同時處理成百上千的鏈路,性能上無法支撐,即便NIO線程的CPU負(fù)荷達(dá)到100%,也無法滿足海量消息的編碼、解碼、讀取和發(fā)送;

  2. 當(dāng)NIO線程負(fù)載過重之后,處理速度將變慢,這會導(dǎo)致大量客戶端連接超時,超時之后往往會進行重發(fā),這更加重了NIO線程的負(fù)載,最終會導(dǎo)致大量消息積壓和處理超時,NIO線程會成為系統(tǒng)的性能瓶頸;

  3. 可靠性問題:一旦NIO線程意外跑飛,或者進入死循環(huán),會導(dǎo)致整個系統(tǒng)通信模塊不可用,不能接收和處理外部消息,造成節(jié)點故障。

為了解決這些問題,演進出了Reactor多線程模型。

Reactor多線程模型:

Rector多線程模型與單線程模型最大的區(qū)別就是有一組NIO線程處理真實的IO操作。

Reactor多線程模型的特點:

  1. 有專門一個NIO線程-Acceptor線程用于監(jiān)聽服務(wù)端,接收客戶端的TCP連接請求;

  2. 網(wǎng)絡(luò)IO操作-讀、寫等由一個NIO線程池負(fù)責(zé),線程池可以采用標(biāo)準(zhǔn)的JDK線程池實現(xiàn),它包含一個任務(wù)隊列和N個可用的線程,由這些NIO線程負(fù)責(zé)消息的讀取、解碼、編碼和發(fā)送;

  3. 1個NIO線程可以同時處理N條鏈路,但是1個鏈路只對應(yīng)1個NIO線程,防止發(fā)生并發(fā)操作問題。

在絕大多數(shù)場景下,Reactor多線程模型都可以滿足性能需求;但是,在極特殊應(yīng)用場景中,一個NIO線程負(fù)責(zé)監(jiān)聽和處理所有的客戶端連接可能會存在性能問題。例如百萬客戶端并發(fā)連接,或者服務(wù)端需要對客戶端的握手消息進行安全認(rèn)證,認(rèn)證本身非常損耗性能。在這類場景下,單獨一個Acceptor線程可能會存在性能不足問題,為了解決性能問題,產(chǎn)生了第三種Reactor線程模型-主從Reactor多線程模型。

即從單線程中由一個線程即監(jiān)聽連接事件、讀寫事件、由完成數(shù)據(jù)讀寫,拆分為由一個線程專門監(jiān)聽各種事件,再由專門的線程池負(fù)責(zé)處理真正的IO數(shù)據(jù)讀寫。

主從Reactor多線程模型

主從Reactor線程模型與Reactor多線程模型的最大區(qū)別就是有一組NIO線程處理連接、讀寫事件。

主從Reactor線程模型的特點是:服務(wù)端用于接收客戶端連接的不再是個1個單獨的NIO線程,而是一個獨立的NIO線程池。Acceptor接收到客戶端TCP連接請求處理完成后(可能包含接入認(rèn)證等),將新創(chuàng)建的SocketChannel注冊到IO線程池(sub reactor線程池)的某個IO線程上,由它負(fù)責(zé)SocketChannel的讀寫和編解碼工作。Acceptor線程池僅僅只用于客戶端的登陸、握手和安全認(rèn)證,一旦鏈路建立成功,就將鏈路注冊到后端subReactor線程池的IO線程上,由IO線程負(fù)責(zé)后續(xù)的IO操作。

即從多線程模型中由一個線程來監(jiān)聽連接事件和數(shù)據(jù)讀寫事件,拆分為一個線程監(jiān)聽連接事件,線程池的多個線程監(jiān)聽已經(jīng)建立連接的套接字的數(shù)據(jù)讀寫事件,另外和多線程模型一樣有專門的線程池處理真正的IO操作。

各自適用場景

NIO適用場景

服務(wù)器需要支持超大量的長時間連接。比如10000個連接以上,并且每個客戶端并不會頻繁地發(fā)送太多數(shù)據(jù)。例如總公司的一個中心服務(wù)器需要收集全國便利店各個收銀機的交易信息,只需要少量線程按需處理維護的大量長期連接。

Jetty、Mina、Netty、ZooKeeper等都是基于NIO方式實現(xiàn)。

BIO適用場景

適用于連接數(shù)目比較小,并且一次發(fā)送大量數(shù)據(jù)的場景,這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中。

文2

NIO是為了彌補IO操作的不足而誕生的,NIO的一些新特性有:非阻塞I/O,選擇器,緩沖以及管道。管道(Channel),緩沖(Buffer) ,選擇器( Selector)是其主要特征。

概念解釋:

Channel——管道實際上就像傳統(tǒng)IO中的流,到任何目的地(或來自任何地方)的所有數(shù)據(jù)都必須通過一個 Channel 對象。一個 Buffer 實質(zhì)上是一個容器對象。

Selector——選擇器用于監(jiān)聽多個管道的事件,使用傳統(tǒng)的阻塞IO時我們可以方便的知道什么時候可以進行讀寫,而使用非阻塞通道,我們需要一些方法來知道什么時候通道準(zhǔn)備好了,選擇器正是為這個需要而誕生的。

NIO和傳統(tǒng)的IO有什么區(qū)別呢?

1,IO是面向流的,NIO是面向塊(緩沖區(qū))的。

IO面向流的操作一次一個字節(jié)地處理數(shù)據(jù)。一個輸入流產(chǎn)生一個字節(jié)的數(shù)據(jù),一個輸出流消費一個字節(jié)的數(shù)據(jù)。,導(dǎo)致了數(shù)據(jù)的讀取和寫入效率不佳;

NIO面向塊的操作在一步中產(chǎn)生或者消費一個數(shù)據(jù)塊。按塊處理數(shù)據(jù)比按(流式的)字節(jié)處理數(shù)據(jù)要快得多,同時數(shù)據(jù)讀取到一個它稍后處理的緩沖區(qū),需要時可在緩沖區(qū)中前后移動。這就增加了處理過程中的靈活性。通俗來說,NIO采取了“預(yù)讀”的方式,當(dāng)你讀取某一部分?jǐn)?shù)據(jù)時,他就會猜測你下一步可能會讀取的數(shù)據(jù)而預(yù)先緩沖下來。

2,IO是阻塞的,NIO是非阻塞的。

對于傳統(tǒng)的IO,當(dāng)一個線程調(diào)用read() 或 write()時,該線程被阻塞,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入。該線程在此期間不能再干任何事情了。

而對于NIO,使用一個線程發(fā)送讀取數(shù)據(jù)請求,沒有得到響應(yīng)之前,線程是空閑的,此時線程可以去執(zhí)行別的任務(wù),而不是像IO中那樣只能等待響應(yīng)完成。

NIO和IO適用場景

NIO是為彌補傳統(tǒng)IO的不足而誕生的,但是尺有所短寸有所長,NIO也有缺點,因為NIO是面向緩沖區(qū)的操作,每一次的數(shù)據(jù)處理都是對緩沖區(qū)進行的,那么就會有一個問題,在數(shù)據(jù)處理之前必須要判斷緩沖區(qū)的數(shù)據(jù)是否完整或者已經(jīng)讀取完畢,如果沒有,假設(shè)數(shù)據(jù)只讀取了一部分,那么對不完整的數(shù)據(jù)處理沒有任何意義。所以每次數(shù)據(jù)處理之前都要檢測緩沖區(qū)數(shù)據(jù)。

那么NIO和IO各適用的場景是什么呢?

如果需要管理同時打開的成千上萬個連接,這些連接每次只是發(fā)送少量的數(shù)據(jù),例如聊天服務(wù)器,這時候用NIO處理數(shù)據(jù)可能是個很好的選擇。

而如果只有少量的連接,而這些連接每次要發(fā)送大量的數(shù)據(jù),這時候傳統(tǒng)的IO更合適。使用哪種處理數(shù)據(jù),需要在數(shù)據(jù)的響應(yīng)等待時間和檢查緩沖區(qū)數(shù)據(jù)的時間上作比較來權(quán)衡選擇。

通俗解釋

最后,對于NIO和傳統(tǒng)IO,有一個網(wǎng)友講的生動的例子:

以前的流總是堵塞的,一個線程只要對它進行操作,其它操作就會被堵塞,也就相當(dāng)于水管沒有閥門,你伸手接水的時候,不管水到了沒有,你就都只能耗在接水(流)上。

nio的Channel的加入,相當(dāng)于增加了水龍頭(有閥門),雖然一個時刻也只能接一個水管的水,但依賴輪換策略,在水量不大的時候,各個水管里流出來的水,都可以得到妥

善接納,這個關(guān)鍵之處就是增加了一個接水工,也就是Selector,他負(fù)責(zé)協(xié)調(diào),也就是看哪根水管有水了的話,在當(dāng)前水管的水接到一定程度的時候,就切換一下:臨時關(guān)上當(dāng)

前水龍頭,試著打開另一個水龍頭(看看有沒有水)。

當(dāng)其他人需要用水的時候,不是直接去接水,而是事前提了一個水桶給接水工,這個水桶就是Buffer。也就是,其他人雖然也可能要等,但不會在現(xiàn)場等,而是回家等,可以做

其它事去,水接滿了,接水工會通知他們。

這其實也是非常接近當(dāng)前社會分工細(xì)化的現(xiàn)實,也是統(tǒng)分利用現(xiàn)有資源達(dá)到并發(fā)效果的一種很經(jīng)濟的手段,而不是動不動就來個并行處理,雖然那樣是最簡單的,但也是最浪費

資源的方式。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • NIO(Non-blocking I/O,在Java領(lǐng)域,也稱為New I/O),是一種同步非阻塞的I/O模型,也...
    閃電是只貓閱讀 3,277評論 0 7
  • 姓名:周小蓬 16019110037 轉(zhuǎn)載自:http://blog.csdn.net/u010154380/ar...
    aeytifiw閱讀 650評論 0 1
  • 從三月份找實習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,798評論 11 349
  • 娃娃:1.你昨天上奧數(shù)課了,這是你每天有規(guī)化做奧數(shù)作業(yè)的結(jié)果,又為自己贏得了一天的自由支配時間,恭喜你。2.昨天媽...
    影子3623253閱讀 225評論 0 1
  • 在許多香味中間,我唯獨喜歡薰衣草的淡淡的清香。后來被某人知道了,他花了二百元買了薰衣草的香水??墒撬粫靼啄菐в?..
    天宇超市閱讀 1,106評論 0 0

友情鏈接更多精彩內(nèi)容