<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          京東數(shù)科二面:常見的 IO 模型有哪些?Java 中 BIO、NIO、AIO 的區(qū)別?

          共 3187字,需瀏覽 7分鐘

           ·

          2021-01-29 20:00

          IO 模型這塊確實(shí)挺難理解的,需要太多計(jì)算機(jī)底層知識(shí)。寫這篇文章用了挺久,就非常希望能把我所知道的講出來(lái)吧!希望朋友們能有收貨!為了寫這篇文章,還翻看了一下《UNIX 網(wǎng)絡(luò)編程》這本書,太難了,我滴乖乖!心痛~

          個(gè)人能力有限。如果文章有任何需要補(bǔ)充/完善/修改的地方,歡迎在評(píng)論區(qū)指出,共同進(jìn)步!

          相關(guān)閱讀(原創(chuàng)):淘寶一面:“說(shuō)一下 Spring Boot 自動(dòng)裝配原理唄?”?

          前言

          I/O 一直是很多小伙伴難以理解的一個(gè)知識(shí)點(diǎn),這篇文章我會(huì)將我所理解的 I/O 講給你聽,希望可以對(duì)你有所幫助。

          I/O

          何為 I/O?

          I/O(Input/Outpu) 即輸入/輸出 。

          我們先從計(jì)算機(jī)結(jié)構(gòu)的角度來(lái)解讀一下 I/O。

          根據(jù)馮.諾依曼結(jié)構(gòu),計(jì)算機(jī)結(jié)構(gòu)分為 5 大部分:運(yùn)算器、控制器、存儲(chǔ)器、輸入設(shè)備、輸出設(shè)備。

          馮諾依曼體系結(jié)構(gòu)

          輸入設(shè)備(比如鍵盤)和輸出設(shè)備(比如鼠標(biāo))都屬于外部設(shè)備。網(wǎng)卡、硬盤這種既可以屬于輸入設(shè)備,也可以屬于輸出設(shè)備。

          輸入設(shè)備向計(jì)算機(jī)輸入數(shù)據(jù),輸出設(shè)備接收計(jì)算機(jī)輸出的數(shù)據(jù)。

          從計(jì)算機(jī)結(jié)構(gòu)的視角來(lái)看的話, I/O 描述了計(jì)算機(jī)系統(tǒng)與外部設(shè)備之間通信的過(guò)程。

          我們?cè)傧葟膽?yīng)用程序的角度來(lái)解讀一下 I/O。

          根據(jù)大學(xué)里學(xué)到的操作系統(tǒng)相關(guān)的知識(shí):為了保證操作系統(tǒng)的穩(wěn)定性和安全性,一個(gè)進(jìn)程的地址空間劃分為 用戶空間(User space)內(nèi)核空間(Kernel space ) 。

          像我們平常運(yùn)行的應(yīng)用程序都是運(yùn)行在用戶空間,只有內(nèi)核空間才能進(jìn)行系統(tǒng)態(tài)級(jí)別的資源有關(guān)的操作,比如如文件管理、進(jìn)程通信、內(nèi)存管理等等。也就是說(shuō),我們想要進(jìn)行 IO 操作,一定是要依賴內(nèi)核空間的能力。

          并且,用戶空間的程序不能直接訪問(wèn)內(nèi)核空間。

          當(dāng)想要執(zhí)行 IO 操作時(shí),由于沒(méi)有執(zhí)行這些操作的權(quán)限,只能發(fā)起系統(tǒng)調(diào)用請(qǐng)求操作系統(tǒng)幫忙完成。

          因此,用戶進(jìn)程想要執(zhí)行 IO 操作的話,必須通過(guò) 系統(tǒng)調(diào)用 來(lái)間接訪問(wèn)內(nèi)核空間

          我們?cè)谄匠i_發(fā)過(guò)程中接觸最多的就是 磁盤 IO(讀寫文件)網(wǎng)絡(luò) IO(網(wǎng)絡(luò)請(qǐng)求和相應(yīng))。

          從應(yīng)用程序的視角來(lái)看的話,我們的應(yīng)用程序?qū)Σ僮飨到y(tǒng)的內(nèi)核發(fā)起 IO 調(diào)用(系統(tǒng)調(diào)用),操作系統(tǒng)負(fù)責(zé)的內(nèi)核執(zhí)行具體的 IO 操作。也就是說(shuō),我們的應(yīng)用程序?qū)嶋H上只是發(fā)起了 IO 操作的調(diào)用而已,具體 IO 的執(zhí)行是由操作系統(tǒng)的內(nèi)核來(lái)完成的。

          當(dāng)應(yīng)用程序發(fā)起 I/O 調(diào)用后,會(huì)經(jīng)歷兩個(gè)步驟:

          1. 內(nèi)核等待 I/O 設(shè)備準(zhǔn)備好數(shù)據(jù)
          2. 內(nèi)核將數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間。

          有哪些常見的 IO 模型?

          UNIX 系統(tǒng)下, IO 模型一共有 5 種:同步阻塞 I/O同步非阻塞 I/O、I/O 多路復(fù)用信號(hào)驅(qū)動(dòng) I/O異步 I/O。

          這也是我們經(jīng)常提到的 5 種 IO 模型。

          Java 中 3 種常見 IO 模型

          BIO (Blocking I/O)

          BIO 屬于同步阻塞 IO 模型 。

          同步阻塞 IO 模型中,應(yīng)用程序發(fā)起 read 調(diào)用后,會(huì)一直阻塞,直到在內(nèi)核把數(shù)據(jù)拷貝到用戶空間。

          圖源:《深入拆解Tomcat & Jetty》

          在客戶端連接數(shù)量不高的情況下,是沒(méi)問(wèn)題的。但是,當(dāng)面對(duì)十萬(wàn)甚至百萬(wàn)級(jí)連接的時(shí)候,傳統(tǒng)的 BIO 模型是無(wú)能為力的。因此,我們需要一種更高效的 I/O 處理模型來(lái)應(yīng)對(duì)更高的并發(fā)量。

          NIO (Non-blocking/New I/O)

          Java 中的 NIO 于 Java 1.4 中引入,對(duì)應(yīng) java.nio 包,提供了 Channel , Selector,Buffer 等抽象。NIO 中的 N 可以理解為 Non-blocking,不單純是 New。它支持面向緩沖的,基于通道的 I/O 操作方法。對(duì)于高負(fù)載、高并發(fā)的(網(wǎng)絡(luò))應(yīng)用,應(yīng)使用 NIO 。

          Java 中的 NIO 可以看作是 I/O 多路復(fù)用模型。也有很多人認(rèn)為,Java 中的 NIO 屬于同步非阻塞 IO 模型。

          跟著我的思路往下看看,相信你會(huì)得到答案!

          我們先來(lái)看看 同步非阻塞 IO 模型。

          圖源:《深入拆解Tomcat & Jetty》

          同步非阻塞 IO 模型中,應(yīng)用程序會(huì)一直發(fā)起 read 調(diào)用,等待數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間的這段時(shí)間里,線程依然是阻塞的,直到在內(nèi)核把數(shù)據(jù)拷貝到用戶空間。

          相比于同步阻塞 IO 模型,同步非阻塞 IO 模型確實(shí)有了很大改進(jìn)。通過(guò)輪詢操作,避免了一直阻塞。

          但是,這種 IO 模型同樣存在問(wèn)題:應(yīng)用程序不斷進(jìn)行 I/O 系統(tǒng)調(diào)用輪詢數(shù)據(jù)是否已經(jīng)準(zhǔn)備好的過(guò)程是十分消耗 CPU 資源的。

          這個(gè)時(shí)候,I/O 多路復(fù)用模型 就上場(chǎng)了。

          IO 多路復(fù)用模型中,線程首先發(fā)起 select 調(diào)用,詢問(wèn)內(nèi)核數(shù)據(jù)是否準(zhǔn)備就緒,等內(nèi)核把數(shù)據(jù)準(zhǔn)備好了,用戶線程再發(fā)起 read 調(diào)用。read 調(diào)用的過(guò)程(數(shù)據(jù)從內(nèi)核空間->用戶空間)還是阻塞的。

          目前支持 IO 多路復(fù)用的系統(tǒng)調(diào)用,有 select,epoll 等等。select 系統(tǒng)調(diào)用,是目前幾乎在所有的操作系統(tǒng)上都有支持

          • select 調(diào)用 :內(nèi)核提供的系統(tǒng)調(diào)用,它支持一次查詢多個(gè)系統(tǒng)調(diào)用的可用狀態(tài)。幾乎所有的操作系統(tǒng)都支持。
          • epoll 調(diào)用 :linux 2.6 內(nèi)核,屬于 select 調(diào)用的增強(qiáng)版本,優(yōu)化了 IO 的執(zhí)行效率。

          IO 多路復(fù)用模型,通過(guò)減少無(wú)效的系統(tǒng)調(diào)用,減少了對(duì) CPU 資源的消耗。

          Java 中的 NIO ,有一個(gè)非常重要的選擇器 ( Selector ) 的概念,也可以被稱為 多路復(fù)用器。通過(guò)它,只需要一個(gè)線程便可以管理多個(gè)客戶端連接。當(dāng)客戶端數(shù)據(jù)到了之后,才會(huì)為其服務(wù)。

          AIO (Asynchronous I/O)

          AIO 也就是 NIO 2。Java 7 中引入了 NIO 的改進(jìn)版 NIO 2,它是異步 IO 模型。

          異步 IO 是基于事件和回調(diào)機(jī)制實(shí)現(xiàn)的,也就是應(yīng)用操作之后會(huì)直接返回,不會(huì)堵塞在那里,當(dāng)后臺(tái)處理完成,操作系統(tǒng)會(huì)通知相應(yīng)的線程進(jìn)行后續(xù)的操作。

          目前來(lái)說(shuō) AIO 的應(yīng)用還不是很廣泛。Netty 之前也嘗試使用過(guò) AIO,不過(guò)又放棄了。這是因?yàn)椋琋etty 使用了 AIO 之后,在 Linux 系統(tǒng)上的性能并沒(méi)有多少提升。

          最后,來(lái)一張圖,簡(jiǎn)單總結(jié)一下 Java 中的 BIO、NIO、AIO。

          參考

          • 《深入拆解 Tomcat & Jetty》
          • 如何完成一次 IO:https://llc687.top/post/如何完成一次-io/
          • 程序員應(yīng)該這樣理解 IO:https://www.jianshu.com/p/fa7bdc4f3de7
          • 10 分鐘看懂, Java NIO 底層原理:https://www.cnblogs.com/crazymakercircle/p/10225159.html
          • IO 模型知多少 | 理論篇:https://www.cnblogs.com/sheng-jie/p/how-much-you-know-about-io-models.html
          • 《UNIX 網(wǎng)絡(luò)編程 卷 1;套接字聯(lián)網(wǎng) API 》6.2 節(jié) IO 模型

          推薦??: ?Github掘金計(jì)劃:Github上的一些優(yōu)質(zhì)項(xiàng)目搜羅

          推薦??:V4.0 《JavaGuide 面試突擊版》來(lái)啦!年初搞波大的

          推薦??:Github,永遠(yuǎn)滴神?
          我是 Guide哥,擁抱開源,喜歡烹飪。Github 接近 10w 點(diǎn)贊的開源項(xiàng)目 JavaGuide 的作者。未來(lái)幾年希望持續(xù)完善 JavaGuide,把這一件事情做好足矣!
          我一個(gè)喜歡分享大廠面試真題的技術(shù)人,歡迎點(diǎn)贊分享。咱們下期再會(huì)!
          瀏覽 106
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  北条麻妃亚洲无码 | 亚洲第一成人网址 | 日韩无码免费播放 | 亚洲国产日韩欧美在线a乱码日本中文字幕 欧美三级韩国三级日本三斤在线观看en | 日日操夜夜 |