Java NIO的一些認識

NIO

  • NIO 是一種同步非阻塞的I/O模型

NIO的機制

核心包含三個方面

  • Buffer
  • Channel
  • Selector

Buffer:在NIO中,數據總是從通道(Channel)到緩沖區(qū)(Buffer)扼鞋,又或者是從Buffer寫到Channel中诵原。緩沖區(qū)是一塊可以寫入數據,然后可以從中讀取數據的內存顷蟀,這塊內存被包裝成NIO Buffer對象酒请,用以方便訪問該內存塊。

Channel:傳統(tǒng)的IO處理數據是以字節(jié)流或者字符流的方式來處理的鸣个,而NIO是以Channel來處理數據的羞反,和流的主要區(qū)別在于:一般的流(InputStream 或者OutputStream)是單向的,而Channel既可以讀囤萤,又可以寫昼窗,還能異步的寫與讀。Channel一般封裝了Socket, ByteBuffer等對象涛舍,所以Channel可以看成一個網絡連接澄惊。

Selector:Selector是Java NIO中能夠檢測到一到多個NIO Channel, 并能夠知曉Channel是否為諸如讀寫事件做好準備的組件富雅。這樣一個線程可以管理多個Channel掸驱,從而管理多個網絡連接。

三者之間的對應關系是:



NIO 的線程模型 Reactor

首先是一個前提:CPU的處理速度遠遠高于IO速度

所有的 I/O操作都可以分為兩個部分---等待就緒和讀寫操作

在傳統(tǒng)的BIO模型中没佑,其阻塞就在整個I/O的過程中全部阻塞毕贼,當socket調用了read()或者write()時,線程就會一直堵塞住蛤奢,但是這時候CPU是沒有釋放的鬼癣,但是也沒有進行任何的處理或者計算,所以這時候的CPU是被浪費掉的远剩,而一般來說讀寫操作是非晨勰纾快速的,近乎可以忽略不計瓜晤,所以對于BIO來說锥余,絕大部分時間CPU是處于“空等”的狀態(tài),造成了很大的浪費痢掠,而BIO的性能瓶頸就在這里驱犹。

NIO的非阻塞體現在第一階段(等待就緒)嘲恍,與BIO不同的是,這個時候會采用一種輪詢的向操作系統(tǒng)詢問是否有IO操作到達雄驹,如果有就進行讀寫操作佃牛,沒有也會立即返回,不會阻塞在等待IO的過程中医舆,這樣就可以將CPU釋放去進行其他的計算俘侠。這樣使得線程完全不需要等待IO,就可以完成上千上萬的連接處理請求蔬将。

下面一張圖比較形象直觀表達了這一點:


什么是Reactor模型?
按照wiki的說法是
The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexesthe incoming requests and dispatches them synchronously to the associated request handlers
簡單說來就是一種事件驅動的模式爷速,有一個或者多個輸入源,并且有一個Service handler將這些請求分發(fā)給相應的Request handler霞怀。

從上面那張圖就可以看出來惫东,無論怎樣,總需要一個線程來發(fā)現是否有IO操作毙石,在NIO里廉沮,主要是Selector的來做這個工作

NIO的Reactor模型主要思想是回調,即事件驅動徐矩。一開始的時候向一個線程(即Selector)注冊事件(一般來說是讀寫或者連接事件)滞时,當IO就緒時,這個線程會產生對應一個事件滤灯,然后交由對應的handler進行處理漂洋。

Reactor的單線程和多線程模型主要區(qū)別點在于

  • 單線程模型只有NIO線程對所有的請求連接,讀寫操作進行處理力喷,而多線程模型是一組
  • 多線程模型是專門有一個NIO線程-Acceptor線程用于監(jiān)聽服務端,接收客戶端的請求

NIO和BIO的區(qū)別

  • NIO是同步非阻塞的IO方式演训,BIO是同步并阻塞的IO方式
  • NIO編程復雜弟孟,BIO編程簡單
  • NIO的同步非阻塞實現方式為設置對與客戶端的每個連接都是都會先注冊到多路復用器(關于多路復用器),多路復用輪詢到有IO請求時才啟動一個線程來處理,而BIO是比較簡單的線程阻塞到數據到來
  • BIO的主要性能差在,對于每一個連接都要有一個線程來進行處理样悟,而NIO可以用很少的線程完成大量的連接處理拂募。而線程的上下文切換是非常耗費CPU資源的。

NIO的原理

由前面的描述可以推得NIO的寫法是(以服務端為例):

  1. 先創(chuàng)建一個Channel 窟她,這個Channel是用來作為服務器傳輸數據的通道陈症,并將這個Channel綁定到某個端口上,監(jiān)聽這個端口震糖。
    2.打開Selector录肯,獲取得到一個Selector,然后將Channel注冊到這個這個Selector上吊说,同時注冊相關事件(讀寫或連接等事件)
    3.之后Selector會一直阻塞到有注冊事件的到來论咏,當事件到來時优炬,如果發(fā)現是連接事件,則將會向Selector中再次注冊這個Channel厅贪。讀寫事件交由其他部分來完成

由以上的分析可以看出蠢护,NIO中比較關鍵的就是Selector,Channel养涮,而這些實例的初始化都需要通過SelectorProvider類實現

public static SelectorProvider provider() {
        synchronized (lock) {
            if (provider != null)
                return provider;
            return AccessController.doPrivileged(
                new PrivilegedAction<SelectorProvider>() {
                    public SelectorProvider run() {
                            if (loadProviderFromProperty())
                                return provider;
                            if (loadProviderAsService())
                                return provider;
                            provider = sun.nio.ch.DefaultSelectorProvider.create();
                            return provider;
                        }
                    });
        }
    }

SelectorProvider是什么

直接查閱jdk doc 上面是這么說的
A selector provider is a concrete subclass of this class that has a zero-argument constructor and implements the abstract methods specified below. A given invocation of the Java virtual machine maintains a single system-wide default provider instance, which is returned by the provider method. The first invocation of that method will locate the default provider as specified below.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末葵硕,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子贯吓,更是在濱河造成了極大的恐慌懈凹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宣决,死亡現場離奇詭異蘸劈,居然都是意外死亡,警方通過查閱死者的電腦和手機尊沸,發(fā)現死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門威沫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人洼专,你說我怎么就攤上這事棒掠。” “怎么了屁商?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵烟很,是天一觀的道長。 經常有香客問我蜡镶,道長雾袱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任官还,我火速辦了婚禮芹橡,結果婚禮上,老公的妹妹穿的比我還像新娘望伦。我一直安慰自己林说,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布屯伞。 她就那樣靜靜地躺著腿箩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劣摇。 梳的紋絲不亂的頭發(fā)上珠移,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音,去河邊找鬼剑梳。 笑死唆貌,一個胖子當著我的面吹牛,可吹牛的內容都是我干的垢乙。 我是一名探鬼主播锨咙,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼追逮!你這毒婦竟也來了酪刀?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤钮孵,失蹤者是張志新(化名)和其女友劉穎骂倘,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體巴席,經...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡历涝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了漾唉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荧库。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赵刑,靈堂內的尸體忽然破棺而出分衫,到底是詐尸還是另有隱情,我是刑警寧澤般此,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布蚪战,位于F島的核電站,受9級特大地震影響铐懊,放射性物質發(fā)生泄漏邀桑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一科乎、第九天 我趴在偏房一處隱蔽的房頂上張望概漱。 院中可真熱鬧,春花似錦喜喂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至腻异,卻和暖如春进副,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工影斑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留给赞,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓矫户,卻偏偏與公主長得像片迅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子皆辽,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容

  • Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API柑蛇,可以替代標準的Java I...
    JackChen1024閱讀 7,555評論 1 143
  • NIO(Non-blocking I/O,在Java領域驱闷,也稱為New I/O)耻台,是一種同步非阻塞的I/O模型,也...
    閃電是只貓閱讀 3,109評論 0 7
  • 1空另、Netty基礎入門 Netty是由JBOSS提供的一個java開源框架盆耽。Netty提供異步的、事件驅動的網絡應...
    我是嘻哈大哥閱讀 4,689評論 0 31
  • 約定 有很多人會將Java NIO分為Java NIO和Java NIO2扼菠,分別指jdk1.4引入的新IO和jdk...
    墻角兒的花閱讀 969評論 0 4
  • 跳躍的海豚 激蕩著我眸中春水 潮濕的海風 是你的呢喃低語 鉆進我十萬個毛孔 癢 就像一道閃電擊中我的背脊 擴散 酥...
    空空幻想家閱讀 89評論 0 0