IO中的阻塞、非阻塞、同步、异步概念分析详解
目錄
?
1.什么是I/O編程
2.阻塞、非阻塞、同步、異步分析
2.1 什么是同步、異步
2.2 什么是阻塞和非阻塞
2.3 阻塞、非阻塞和同步、異步的區(qū)別
2.4 編程實(shí)現(xiàn)
3.參考文獻(xiàn)
1.什么是I/O編程
IO在計(jì)算機(jī)中指Input/Output,也就是輸入和輸出。由于程序和運(yùn)行時(shí)數(shù)據(jù)是在內(nèi)存中駐留,由CPU這個(gè)超快的計(jì)算核心來執(zhí)行,涉及到數(shù)據(jù)交換的地方,通常是磁盤、網(wǎng)絡(luò)等,就需要IO接口。
比如你打開瀏覽器,訪問新浪首頁,瀏覽器這個(gè)程序就需要通過網(wǎng)絡(luò)IO獲取新浪的網(wǎng)頁。瀏覽器首先會(huì)發(fā)送數(shù)據(jù)給新浪服務(wù)器,告訴它我想要首頁的HTML,這個(gè)動(dòng)作是往外發(fā)數(shù)據(jù),叫Output,隨后新浪服務(wù)器把網(wǎng)頁發(fā)過來,這個(gè)動(dòng)作是從外面接收數(shù)據(jù),叫Input。所以,通常,程序完成IO操作會(huì)有Input和Output兩個(gè)數(shù)據(jù)流。當(dāng)然也有只用一個(gè)的情況,比如,從磁盤讀取文件到內(nèi)存,就只有Input操作,反過來,把數(shù)據(jù)寫到磁盤文件里,就只是一個(gè)Output操作。
IO編程中,Stream(流)是一個(gè)很重要的概念,可以把流想象成一個(gè)水管,數(shù)據(jù)就是水管里的水,但是只能單向流動(dòng)。Input Stream就是數(shù)據(jù)從外面(磁盤、網(wǎng)絡(luò))流進(jìn)內(nèi)存,Output Stream就是數(shù)據(jù)從內(nèi)存流到外面去。對(duì)于瀏覽網(wǎng)頁來說,瀏覽器和新浪服務(wù)器之間至少需要建立兩根水管,才可以既能發(fā)數(shù)據(jù),又能收數(shù)據(jù)。
小結(jié)一下,程序運(yùn)行是依靠cpu和內(nèi)存來進(jìn)行的,I/O操作是相對(duì)于內(nèi)存而言的,從外部設(shè)備進(jìn)入內(nèi)存就叫Input,反之從內(nèi)存輸出到外部設(shè)備就叫Output.?
I/O按照設(shè)備來分的話,分為兩種,其一是網(wǎng)絡(luò)I/O,也就是通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)的拉取和輸出。還有一種是磁盤I/O,主要是對(duì)磁盤進(jìn)行讀寫工作。?
2.阻塞、非阻塞、同步、異步分析
由于CPU和內(nèi)存的速度遠(yuǎn)遠(yuǎn)高于外設(shè)的速度,所以,在IO編程中,就存在速度嚴(yán)重不匹配的問題。舉個(gè)例子來說,比如要把100M的數(shù)據(jù)寫入磁盤,CPU輸出100M的數(shù)據(jù)只需要0.01秒,可是磁盤要接收這100M數(shù)據(jù)可能需要10秒,怎么辦呢??
這就牽扯出來了同步、異步、阻塞與非阻塞這些概念。
舉一個(gè)燒水的例子來具體解釋這幾個(gè)概念。?
說到燒水,我們都是通過熱水壺來燒水的。在很久之前,科技還沒有這么發(fā)達(dá)的時(shí)候,如果我們要燒水,需要把水壺放到火爐上,我們通過觀察水壺內(nèi)的水的沸騰程度來判斷水有沒有燒開。
隨著科技的發(fā)展,現(xiàn)在市面上的水壺都有了提醒功能,當(dāng)我們把水壺插電之后,水壺水燒開之后會(huì)通過聲音提醒我們水開了。
2.1 什么是同步、異步
對(duì)于燒水這件事兒來說,傳統(tǒng)水壺的燒水就是同步的,高科技水壺的燒水就是異步的。
同步請(qǐng)求,A調(diào)用B,B的處理是同步的,在處理完之前他不會(huì)通知A,只有處理完之后才會(huì)明確的通知A。
異步請(qǐng)求,A調(diào)用B,B的處理是異步的,B在接到請(qǐng)求后先告訴A我已經(jīng)接到請(qǐng)求了,然后異步去處理,處理完之后通過回調(diào)等方式再通知A。
所以說,同步和異步最大的區(qū)別就是被調(diào)用方的執(zhí)行方式和返回時(shí)機(jī)。同步指的是被調(diào)用方做完事情之后再返回,異步指的是被調(diào)用方先返回,然后再做事情,做完之后再想辦法通知調(diào)用方。
2.2 什么是阻塞和非阻塞
還是那個(gè)燒水的例子,當(dāng)你把水放到水壺里面,按下開關(guān)后,你可以坐在水壺前面,別的事情什么都不做,一直等著水燒好。你還可以先去客廳看電視,等著水開就好了。
對(duì)于你來說,坐在水壺前面等就是阻塞的,去客廳看電視等著水開就是非阻塞的。
阻塞請(qǐng)求,A調(diào)用B,A一直等著B的返回,別的事情什么也不干。
非阻塞請(qǐng)求,A調(diào)用B,A不用一直等著B的返回,先去忙別的事情了。
所以說,同步和異步最大的區(qū)別就是在被調(diào)用方返回結(jié)果之前的這段時(shí)間內(nèi),調(diào)用方是否一直等待。阻塞指的是調(diào)用方一直等待別的事情什么都不做。非阻塞指的是調(diào)用方先去忙別的事情。
2.3 阻塞、非阻塞和同步、異步的區(qū)別
有人認(rèn)為阻塞和同步是一回事兒,非阻塞和異步是一回事。但是這是不對(duì)的。
首先,前面已經(jīng)提到過,阻塞、非阻塞和同步、異步其實(shí)針對(duì)的對(duì)象是不一樣的。阻塞、非阻塞說的是調(diào)用者,同步、異步說的是被調(diào)用者。
針對(duì)于上文所說的燒水的案例來說,阻塞與非阻塞是形容調(diào)用者人的,而同步和異步是形容被調(diào)用者燒水這件事兒。?
同步里面可以有阻塞的情形,也可以有非阻塞的性情。異步也可以有阻塞的情形和非阻塞的情形。?
先來看同步場(chǎng)景中是如何包含阻塞和非阻塞情況的
我們是用傳統(tǒng)的水壺?zé)T谒疅_之前我們一直做在水壺前面,等著水開。這就是阻塞的。
我們是用傳統(tǒng)的水壺?zé)T谒疅_之前我們先去客廳看電視了,但是水壺不會(huì)主動(dòng)通知我們,需要我們時(shí)不時(shí)的去廚房看一下水有沒有燒開。這就是非阻塞的。
再來看異步場(chǎng)景中是如何包含阻塞和非阻塞情況的
我們是用帶有提醒功能的水壺?zé)T谒疅l(fā)出提醒之前我們一直做在水壺前面,等著水開。這就是阻塞的。
我們是用帶有提醒功能的水壺?zé)T谒疅l(fā)出提醒之前我們先去客廳看電視了,等水壺發(fā)出聲音提醒我們。這就是非阻塞的。
2.4 編程實(shí)現(xiàn)
在真實(shí)的編程環(huán)境中,阻塞、非阻塞和同步、異步之間的組合并不是都存在的。
在Java語言中,一共提供了三種IO模型,分別是阻塞IO(BIO)、非阻塞IO(NIO)、異步IO(AIO)。
這里面的BIO和NIO都是同步的IO模型,即同步阻塞IO和同步非阻塞IO,異步IO指的是異步非阻塞IO。
BIO (Blocking I/O):同步阻塞I/O模式,數(shù)據(jù)的讀取寫入必須阻塞在一個(gè)線程內(nèi)等待其完成。
NIO (New I/O):同時(shí)支持阻塞與非阻塞模式,但主要是使用同步非阻塞IO。
AIO (Asynchronous I/O):異步非阻塞I/O模型。
可以拿燒水的例子來解釋這三種I/O模型
BIO (Blocking I/O):有一排水壺在燒開水,BIO的工作模式就是,叫一個(gè)線程停留在一個(gè)水壺那,直到這個(gè)水壺?zé)_,才去處理下一個(gè)水壺。但是實(shí)際上線程在等待水壺?zé)_的時(shí)間段什么都沒有做。
NIO (New I/O):NIO的做法是叫一個(gè)線程不斷的輪詢每個(gè)水壺的狀態(tài),看看是否有水壺的狀態(tài)發(fā)生了改變,從而進(jìn)行下一步的操作。
AIO ( Asynchronous I/O):為每個(gè)水壺上面裝了一個(gè)開關(guān),水燒開之后,水壺會(huì)自動(dòng)通知我水燒開了。
3.參考文獻(xiàn)
廖雪峰官方文檔
微信公眾號(hào):漫話編程
?
總結(jié)
以上是生活随笔為你收集整理的IO中的阻塞、非阻塞、同步、异步概念分析详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一文了解Linux 网络 I/O 模型
- 下一篇: IntelliJ IDEA不好用?那是因