新聞中心
首先,我們需要弄清楚幾個(gè)概念:同步和異步,阻塞和非阻塞。

創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),婁煩企業(yè)網(wǎng)站建設(shè),婁煩品牌網(wǎng)站建設(shè),網(wǎng)站定制,婁煩網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,婁煩網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
同步和異步
1. 同步
進(jìn)程觸發(fā) IO 操作的時(shí)候,必須親自處理;
比如你必須親自去銀行取錢。
2. 異步
進(jìn)程觸發(fā) IO 操作的時(shí)候,可以不親自處理,它把操作委托給 OS 處理,委托的時(shí)候需要告知數(shù)據(jù)的地址和大小,然后自己去做別的事情,當(dāng) IO 操作結(jié)束后會(huì)得到通知;
比如你把銀行卡給我,讓我?guī)湍闳ャy行取錢,你需要告訴我銀行卡密碼和取多少錢,我取完了之后把錢給你。
3. 總結(jié)
自己干就是同步,別人干就是異步。
阻塞和非阻塞
1. 阻塞
進(jìn)程觸發(fā) IO 操作的時(shí)候,如果此時(shí)此時(shí)沒辦法讀或者寫,那么進(jìn)程就一直等待,直到讀寫結(jié)束;
比如你去銀行 ATM 取錢,前面有人在排隊(duì),那么就要一直等待,直到你取完錢;
2. 非阻塞
進(jìn)程觸發(fā) IO 操作的時(shí)候,如果此時(shí)此時(shí)沒辦法讀或者寫,那么就先去做別的,等到有通知后,再繼續(xù)讀寫;
比如你去銀行柜臺(tái)取錢,人比較多,那就先領(lǐng)一個(gè)號(hào),等著叫到號(hào)再去對(duì)應(yīng)的窗口辦理業(yè)務(wù);這里稍微有些不太恰當(dāng)?shù)氖?,我們等待的過程中,還得聽著叫號(hào)。
3. 總結(jié)
我要等著不能做其他事就是阻塞,我不用等可以做其他事就是異步。
BIO
同步阻塞;一個(gè)請(qǐng)求過來,應(yīng)用程序開了一個(gè)線程,等 IO 準(zhǔn)備好,IO 操作也是自己干;
采用 BIO 模型的服務(wù)端,由一個(gè)獨(dú)立的 Acceptor 線程負(fù)責(zé)進(jìn)行監(jiān)聽;在 while(true) 循環(huán)中調(diào)用 accept() 方法,等待客戶端的請(qǐng)求;
一旦接收到請(qǐng)求,就可以建立套接字開始進(jìn)行讀寫操作,這時(shí)候不再接收其他的請(qǐng)求,直到讀寫完成;
為了讓 BIO 能夠同時(shí)處理多個(gè)請(qǐng)求,那么就需要使用多線程處理;當(dāng)服務(wù)端接收到請(qǐng)求,就為客戶端創(chuàng)建一個(gè)線程進(jìn)行處理,處理完成后再做線程銷毀;
不過因?yàn)橐粋€(gè)請(qǐng)求就要啟動(dòng)一個(gè)線程,所以開銷是比較大的,啟動(dòng)和銷毀線程開銷很大,而且每個(gè)線程都要占用內(nèi)存,所以可以引入線程池,可以在一定程度上減少線程創(chuàng)建和銷毀的開銷;這也被叫做 偽異步 IO。
線程池維護(hù)著 N 個(gè)線程和一個(gè)消息隊(duì)列;當(dāng)有請(qǐng)求接入時(shí),服務(wù)端將 Socket 作為參數(shù)傳遞到一個(gè)線程任務(wù)中進(jìn)行處理;通過對(duì)線程池最大線程數(shù)和消息隊(duì)列大小進(jìn)行控制,所以就算訪問量高于服務(wù)端的承載能力,也不會(huì)因?yàn)榉?wù)端的資源耗盡而導(dǎo)致宕機(jī);
這個(gè)模型在 請(qǐng)求量不高的時(shí)候,效率還是不錯(cuò)的,而且也不需要考慮限流的問題(控制線程池的最大線程數(shù)量)。
NIO
同步非阻塞;不用等待 IO 準(zhǔn)備,準(zhǔn)備好了會(huì)通知,不過 IO 操作還是要自己干;NIO 是一種多路復(fù)用機(jī)制,利用單線程輪詢事件,Channel 來決定做什么,避免連接數(shù)多的時(shí)候,頻繁進(jìn)行線程切換導(dǎo)致性能問題(Select 階段阻塞)。
聽到這里,很多人可能已經(jīng)懵了...什么是多路復(fù)用?Channel又是啥?Select 階段到底是什么階段?這里我用白話解釋一下。
NIO是面向緩沖區(qū)的,可以將數(shù)據(jù)讀取到一個(gè)緩沖區(qū),稍后進(jìn)行處理。NIO 有幾個(gè)核心概念:
1. Channel 和 Buffer
Channel 可以理解成一個(gè)雙向流,或者理解成一個(gè)通道,Buffer 就是緩存區(qū),或者你就把它看做是一塊內(nèi)存空間,數(shù)據(jù)可以從 Channel 流進(jìn) Buffer ,也可以從 Buffer 流進(jìn) Channel 。
Channel 有很多種實(shí)現(xiàn),比如:FileChannel 是從文件中讀寫數(shù)據(jù),SocketChannel 通過 TCP 讀寫網(wǎng)絡(luò)中的數(shù)據(jù)等等。
Buffer 也有多重類型,比如:ByteBuffer、CharBuffer、IntBuffer等等,光看他們的名字就知道他們代表了不同的數(shù)據(jù)類型。
2. Selector
我們可以把 Selector 看做是一個(gè)管理員,可以管理多個(gè) Channel , Selector 能夠知道到哪個(gè) Channel 已經(jīng)做好了讀寫的準(zhǔn)備。這樣一個(gè)線程只要操作這個(gè)管理員就可以了,相當(dāng)于一個(gè)線程可以管理多個(gè) Channel;一旦監(jiān)聽到有準(zhǔn)備好的 Channel,就可以進(jìn)行相應(yīng)的處理。
不過 Java 原生的 NIO 不好用,直到 Netty 的出現(xiàn)。
AIO
異步非阻塞;因?yàn)槭虑椴皇亲约鹤?,其?shí)也沒有阻塞一說(都是非阻塞);
AIO 是在 NIO 的基礎(chǔ)上,引入異步通道的概念;NIO 是采用輪詢的方式,不停地詢問數(shù)據(jù)是否準(zhǔn)備好了,準(zhǔn)備好了就處理;AIO 是向操作系統(tǒng)注冊(cè) IO 監(jiān)聽,操作系統(tǒng)完成 IO 操作了之后,主動(dòng)通知,觸發(fā)響應(yīng)的函數(shù)(自己不做,讓操作系統(tǒng)來做)。
目前看,AIO 應(yīng)該的還不是很廣泛。
看過這篇文章之后,您是否對(duì) BIO、NIO 和 AIO 有了初步的了解呢?
分享名稱:還搞不懂JavaNIO?快來讀讀這篇文章
新聞來源:http://fisionsoft.com.cn/article/cdohpos.html


咨詢
建站咨詢
