Java NIO學(xué)習(xí)筆記 - NIO編程知識(shí)

NIO編程

在介紹NIO編程之前唯鸭,我們首先需要澄清一個(gè)概念:NIO到底是什么的簡(jiǎn)稱(chēng)盼忌?有人稱(chēng)之為New I/O再愈,因?yàn)樗鄬?duì)于之前的I/O類(lèi)庫(kù)是新增的奠伪,所以被稱(chēng)為New I/O跌帐,這是它的官方叫法。但是绊率,由于之前老的I/O類(lèi)庫(kù)是阻塞I/O谨敛,New I/O類(lèi)庫(kù)的目標(biāo)就是要讓Java支持非阻塞I/O,所以滤否,更多的人喜歡稱(chēng)之為非阻塞I/O(Non-block I/O)脸狸,由于非阻塞I/O更能夠體現(xiàn)NIO的特點(diǎn),所以我們這里使用NIO表示非阻塞I/O藐俺。

與Socket類(lèi)和ServerSocket類(lèi)相對(duì)應(yīng)炊甲,NIO也提供了SocketChannel和ServerSocketChannel兩種不同的套接字通道實(shí)現(xiàn)泥彤。這兩種新增的通道都支持阻塞和非阻塞兩種模式。阻塞模式使用非常簡(jiǎn)單卿啡,但是性能和可靠性都不好吟吝,非阻塞模式則正好相反。開(kāi)發(fā)人員一般可以根據(jù)自己的需要來(lái)選擇合適的模式牵囤,一般來(lái)說(shuō)爸黄,低負(fù)載,低并發(fā)的應(yīng)用程序可以選擇同步阻塞I/O以降低編程復(fù)雜度揭鳞,但是對(duì)于高負(fù)載炕贵,高并發(fā)的網(wǎng)絡(luò)應(yīng)用,需要使用NIO的非阻塞模式進(jìn)行開(kāi)發(fā)野崇。

NIO類(lèi)庫(kù)簡(jiǎn)介

1. 緩沖區(qū)Buffer

我們首先介紹緩沖區(qū)(Buffer)的概念称开,Buffer是一個(gè)對(duì)象,它包含一些要寫(xiě)入或者要讀出的數(shù)據(jù)。在NIO類(lèi)庫(kù)中加入Buffer對(duì)象,體現(xiàn)了新庫(kù)與原I/O的一個(gè)重要區(qū)別洒宝。在面向流的I/O中,可以將數(shù)據(jù)直接寫(xiě)入或者將數(shù)據(jù)直接讀到Stream對(duì)象中蕴侣。

在NIO庫(kù)中,所有數(shù)據(jù)都是用緩沖區(qū)處理的臭觉。在讀取數(shù)據(jù)時(shí)昆雀,它是直接讀到緩沖區(qū)中的;在寫(xiě)入數(shù)據(jù)時(shí)蝠筑,寫(xiě)入到緩沖區(qū)中狞膘。任何時(shí)候訪問(wèn)NIO中的數(shù)據(jù),都是通過(guò)緩沖區(qū)進(jìn)行操作什乙。

緩沖區(qū)實(shí)質(zhì)上是一個(gè)數(shù)組挽封。通常它是一個(gè)字節(jié)數(shù)組(ByteBuffer),也可以使用其他種類(lèi)的數(shù)組臣镣。但是一個(gè)緩沖區(qū)不僅僅是一個(gè)數(shù)組辅愿,緩沖區(qū)提供了對(duì)數(shù)據(jù)的結(jié)構(gòu)化訪問(wèn)以及維護(hù)讀寫(xiě)位置(limit)等信息。

最常用的緩沖區(qū)是ByteBuffer忆某,一個(gè)ByteBuffer提供了一組功能用于操作byte數(shù)組渠缕。除了ByteBuffer,還有其他的一些緩沖區(qū)褒繁,事實(shí)上,每一種Java基本類(lèi)型(除了Boolean類(lèi)型)都對(duì)應(yīng)有一種緩沖區(qū)馍忽,具體如下:

  • ByteBuffer:字節(jié)緩沖區(qū)
  • CharBuffer:字符緩沖區(qū)
  • ShortBuffer:短整型緩沖區(qū)
  • IntBuffer:整型緩沖區(qū)
  • LongBuffer:長(zhǎng)整型緩沖區(qū)
  • FloatBuffer:浮點(diǎn)型緩沖區(qū)
  • DoubleBuffer:雙精度浮點(diǎn)型緩沖區(qū)

緩沖區(qū)的繼承關(guān)系如下圖所示:

buffer.png

每一個(gè)Buffer類(lèi)都是Buffer接口的一個(gè)子實(shí)例棒坏。除了ByteBuffer燕差,每一個(gè)Buffer類(lèi)都有完全一樣的操作,只是它們所處理的數(shù)據(jù)類(lèi)型不一樣坝冕。因?yàn)榇蠖鄶?shù)標(biāo)準(zhǔn)I/O操作都使用ByteBuffer徒探,所以它除了具有一般緩沖區(qū)的操作之外還提供一些特有的操作,方便網(wǎng)絡(luò)讀寫(xiě)喂窟。

2. 通道Channel

Channel是一個(gè)通道测暗,可以通過(guò)它讀取和寫(xiě)入數(shù)據(jù),它就像輸水管道一樣磨澡,網(wǎng)絡(luò)數(shù)據(jù)通過(guò)Channel讀取和寫(xiě)入碗啄。通道與流的不同之處在于通道是雙向的,流只是在一個(gè)方向上移動(dòng)(一個(gè)流必須是InputStream 或者 OutputStream的子類(lèi))稳摄,而且通道可以用于讀稚字,寫(xiě)或者同時(shí)用于讀寫(xiě)。

因?yàn)镃hannel是全雙工的厦酬,所以它可以比流更好地映射底層操作系統(tǒng)的API胆描。特別是在UNIX網(wǎng)絡(luò)編程模型中,底層操作系統(tǒng)的通道都是全雙工的仗阅,同時(shí)支持讀寫(xiě)操作昌讲。

Channel的集成關(guān)系如下圖所示:

channel.png

自頂向下看, 前三層主要是Channel接口减噪,用于定義它的功能短绸,后面是一些具體的功能類(lèi)(抽象類(lèi))。從類(lèi)圖可以看出旋廷,實(shí)際上Channel可以分為兩大類(lèi):分別是用于網(wǎng)絡(luò)讀寫(xiě)的SelectableChannel和用于文件操作的FileChannel鸠按。本節(jié)涉及的ServerSocketChannel和SocketChannel都是SelectableChannel的子類(lèi)。

3. 多路復(fù)用器Selector

多路復(fù)用器Selector饶碘,它是Java NIO編程的基礎(chǔ)目尖,熟練地掌握Selector對(duì)于掌握NIO編程至關(guān)重要。多路復(fù)用器提供選擇已經(jīng)就緒的任務(wù)的能力扎运。簡(jiǎn)單來(lái)講瑟曲,** Selector會(huì)不斷地輪詢(xún)注冊(cè)在其上的Channel,如果某個(gè)Channel上面有新的TCP連接接入豪治,讀和寫(xiě)事件洞拨,這個(gè)Channel就處于就緒狀態(tài),會(huì)被Selector輪詢(xún)出來(lái)负拟,然后通過(guò)SelectionKey可以獲取就緒Channel的集合烦衣,進(jìn)行后續(xù)的I/O操作** 。

** 一個(gè)多路復(fù)用器Selector可以同時(shí)輪詢(xún)多個(gè)Channel,由于JDK使用了epoll()代替?zhèn)鹘y(tǒng)的select實(shí)現(xiàn)花吟,所以它并沒(méi)有最大連接句柄1024/2048的限制秸歧。這也就意味著只需要一個(gè)線程負(fù)責(zé)Selector的輪詢(xún),就可以接入成千上萬(wàn)的客戶(hù)端衅澈,這確實(shí)是個(gè)非常巨大的進(jìn)步键菱。**

參考資料

理解Java NIO

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市今布,隨后出現(xiàn)的幾起案子经备,更是在濱河造成了極大的恐慌,老刑警劉巖部默,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侵蒙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡甩牺,警方通過(guò)查閱死者的電腦和手機(jī)蘑志,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贬派,“玉大人急但,你說(shuō)我怎么就攤上這事「惴Γ” “怎么了波桩?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)请敦。 經(jīng)常有香客問(wèn)我镐躲,道長(zhǎng),這世上最難降的妖魔是什么侍筛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任萤皂,我火速辦了婚禮,結(jié)果婚禮上匣椰,老公的妹妹穿的比我還像新娘裆熙。我一直安慰自己,他們只是感情好禽笑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布入录。 她就那樣靜靜地躺著,像睡著了一般佳镜。 火紅的嫁衣襯著肌膚如雪僚稿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天蟀伸,我揣著相機(jī)與錄音蚀同,去河邊找鬼缅刽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唤崭,可吹牛的內(nèi)容都是我干的拷恨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼谢肾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了小泉?” 一聲冷哼從身側(cè)響起芦疏,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎微姊,沒(méi)想到半個(gè)月后酸茴,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兢交,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年薪捍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片配喳。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡酪穿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晴裹,到底是詐尸還是另有隱情被济,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布涧团,位于F島的核電站只磷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泌绣。R本人自食惡果不足惜钮追,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阿迈。 院中可真熱鬧元媚,春花似錦、人聲如沸仿滔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)崎页。三九已至鞠绰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間飒焦,已是汗流浹背蜈膨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工屿笼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人翁巍。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓驴一,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親灶壶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肝断,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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