BIO,NIO,AIO

都說生產(chǎn)碰到的問題會(huì)印象深刻,由于web應(yīng)用部署使用了公司內(nèi)部框架,需要進(jìn)行參數(shù)優(yōu)化,對(duì)此進(jìn)行了一番了解

BIO,NIO,AIO參考資料:
十分鐘了解BIO,NIO,AIO(http://loveshisong.cn/%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF/2016-06-25-%E5%8D%81%E5%88%86%E9%92%9F%E4%BA%86%E8%A7%A3BIO-NIO-AIO.html

之前看很多資料,都混淆了一些技術(shù)點(diǎn),
理解了之后覺得特別重要的有:

  • 同步和異步,阻塞和非阻塞 ,這個(gè)是理解的基礎(chǔ),2個(gè)緯度的概念
    同步和異步的關(guān)注點(diǎn)在于邏輯上流程是否是一步步執(zhí)行的,是否一定要按順序執(zhí)行
    阻塞和非阻塞的關(guān)注點(diǎn):指請(qǐng)求結(jié)果返回之前, 當(dāng)前線程會(huì)被掛起(被阻塞)

  • IO模型:
    Java中的IO操作是JVM配合操作系統(tǒng)來完成的. 對(duì)于一個(gè)IO的讀操作, 數(shù)據(jù)會(huì)先被拷貝到操作系統(tǒng)內(nèi)核的緩沖區(qū)中, 然后從操作系統(tǒng)內(nèi)核的緩沖區(qū)拷貝到應(yīng)用程序的地址空間. 所以整個(gè)過程可分為兩個(gè)階段:
    1.等待I/O數(shù)據(jù)準(zhǔn)備好. 這取決于IO目標(biāo)返回?cái)?shù)據(jù)的速度, 如網(wǎng)絡(luò)IO時(shí)看網(wǎng)速和數(shù)據(jù)本身的大小.
    2.數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到進(jìn)程內(nèi).
    根據(jù)這兩個(gè)階段, 產(chǎn)生了常見的幾種不同的IO模型: BIO, NIO, IO多路復(fù)用和AIO.

  • BIO blcoking IO,最易理解的概念


    image.png

    程序發(fā)送請(qǐng)求給內(nèi)核, 然后由內(nèi)核去進(jìn)行通信, 在內(nèi)核準(zhǔn)備好數(shù)據(jù)之前這個(gè)線程是被掛起的, 所以在兩個(gè)階段程序都處于掛起狀態(tài).
    BIO的特點(diǎn)就是在IO執(zhí)行的兩個(gè)階段都被block了。提升性能的主要方法就是多起一些線程。

  • NIO和多路復(fù)用,這是2個(gè)概念,只不過經(jīng)常一起用罷了

  • NIO NON BLOCKING IO


    image.png

    顧名思義,非阻塞IO
    NIO的特點(diǎn)就是在第一個(gè)階段,系統(tǒng)內(nèi)核準(zhǔn)備數(shù)據(jù)的階段,應(yīng)用程序線程需要不斷的主動(dòng)詢問內(nèi)核數(shù)據(jù)是否準(zhǔn)備好,此階段可以做其他事,不回被掛起。第一個(gè)階段非阻塞, 第二個(gè)階段阻塞

  • IO多路復(fù)用
    IO多路復(fù)用(I/O Multiplexing)有select, poll, epoll等不同方式, 它的優(yōu)點(diǎn)在于單個(gè)線程可以同時(shí)處理多個(gè)網(wǎng)絡(luò)IO.
    從NIO的角度進(jìn)行優(yōu)化,NIO中輪詢操作是用戶線程進(jìn)行的, 如果把這個(gè)任務(wù)交給其他線程, 則用戶線程就不用這么費(fèi)勁的查詢狀態(tài)了. IO多路復(fù)用調(diào)用系統(tǒng)級(jí)別的select或poll模型, 由系統(tǒng)進(jìn)行監(jiān)控IO狀態(tài). select輪詢可以監(jiān)控許多socket的IO請(qǐng)求, 當(dāng)有一個(gè)socket的數(shù)據(jù)準(zhǔn)備好時(shí)就可以返回

select: 注冊(cè)事件由數(shù)組管理, 數(shù)組是有長度的, 32位機(jī)上限1024, 64位機(jī)上限2048. 輪詢查找時(shí)需要遍歷數(shù)組.
poll: 把select的數(shù)組采用鏈表實(shí)現(xiàn), 因此沒了最大數(shù)量的限制
epoll方式: 基于事件回調(diào)機(jī)制, 回調(diào)時(shí)直接通知進(jìn)程, 無須使用某種方式來查看狀態(tài).

這三者其實(shí)都是實(shí)現(xiàn)多路復(fù)用的方式

  • 此處需要擴(kuò)展
    1.最簡單的方式,讓應(yīng)用本身起一個(gè)單獨(dú)的線程,一直去遍歷socket的列表 ,缺點(diǎn)是連接空閑時(shí),也會(huì)占用cpu資源
    2.事件驅(qū)動(dòng)的方式,對(duì)1的改進(jìn)。將遍歷的工作交給系統(tǒng)內(nèi)核。內(nèi)核將遍歷結(jié)果組織成事件列表返回給應(yīng)用層處理。缺點(diǎn),當(dāng)套接字連接數(shù)量變大,列表從內(nèi)核復(fù)制到應(yīng)用也是不小的開銷。此外,當(dāng)活躍連接較少時(shí),存在很多無效的數(shù)據(jù)副本,因?yàn)樗鼘⒒钴S和不活躍的鏈接狀態(tài)都復(fù)制到應(yīng)用層
    3.內(nèi)核基于回調(diào)的事件監(jiān)測
    對(duì)于遍歷的機(jī)制進(jìn)行優(yōu)化!內(nèi)核每個(gè)套接字都對(duì)應(yīng)一個(gè)回調(diào)函數(shù)。當(dāng)客戶端發(fā)送數(shù)據(jù)時(shí),內(nèi)核從網(wǎng)卡接收數(shù)據(jù)庫就會(huì)調(diào)用回調(diào)函數(shù)。在回調(diào)函數(shù)中維護(hù)事件列表。應(yīng)用層獲取此事件列表即可
image.png

多路復(fù)用IO的特點(diǎn)是用戶進(jìn)程能同時(shí)等待多個(gè)IO請(qǐng)求, 系統(tǒng)來監(jiān)控IO狀態(tài), 其中的任意一個(gè)進(jìn)入讀就緒狀態(tài), select函數(shù)就可以返回.

*AIO
前面講的都是同步方法,至少第二階段是同步的,只有AIO才是異步方法
AIO即Asynchronous I/O(異步 I/O), 這是Java 1.7引入的NIO 2.0中用到的. 整個(gè)過程中, 用戶線程發(fā)起一個(gè)系統(tǒng)調(diào)用之后無須等待, 可以處理別的事情. 由操作系統(tǒng)等待接收內(nèi)容, 接收后把數(shù)據(jù)拷貝到用戶進(jìn)程中, 最后通知用戶程序已經(jīng)可以使用數(shù)據(jù)了, 兩個(gè)階段都是非阻塞的. AIO整個(gè)過程如下圖:


image.png

AIO屬于異步模型, 用戶線程可以同時(shí)處理別的事情, 我們?cè)趺催M(jìn)一步加工處理結(jié)果呢? Java在這個(gè)模型中提供了兩種方法:
一種是基于”回調(diào)”, 我們可以實(shí)現(xiàn)CompletionHandler接口, 在調(diào)用時(shí)把回調(diào)函數(shù)傳遞給對(duì)應(yīng)的API即可
另一種是返回一個(gè)Future. 處理完別的事情, 可以通過isDone()可查看是否已經(jīng)準(zhǔn)備好數(shù)據(jù), 通過get()方法等待返回?cái)?shù)據(jù).

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

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

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