一篇文章理解阻塞、非阻塞、同步、異步
理解阻塞、非阻塞、同步、異步
首先說(shuō)明,這些都是在特點(diǎn)場(chǎng)景下或者相對(duì)情況的詞匯,OK,接下來(lái)開(kāi)門(mén)見(jiàn)山。
阻塞
可以很直觀的理解,就如節(jié)假日高速路出口收費(fèi)站一樣,上圖片:

9個(gè)收費(fèi)亭,同時(shí)來(lái)了一大波車(chē),這時(shí)候同一時(shí)刻只能有9輛車(chē)在收費(fèi),剩下的車(chē)都在只能在后面排隊(duì)等待,這就是現(xiàn)實(shí)中很直觀的阻塞現(xiàn)象。這9個(gè)收費(fèi)亭,就是一個(gè)瓶頸,或許畫(huà)為這樣更符合大家對(duì)瓶頸二字的理解:

第1張圖中,高速公路源源不斷的車(chē)輛到來(lái),和第二張圖的效果其實(shí)表示一樣。
OK,看圖明白了現(xiàn)象,分析一下為什么會(huì)阻塞?
1.數(shù)量上:
到來(lái)車(chē)輛數(shù)——大量
收費(fèi)站數(shù)——小于等于9個(gè)
結(jié)論:在要過(guò)卡的汽車(chē)數(shù)量大于收費(fèi)亭數(shù)量時(shí),就會(huì)有阻塞現(xiàn)象。
2.速度上:
到來(lái)車(chē)輛速度——快速
收費(fèi)站過(guò)卡速度——慢
結(jié)論:在收費(fèi)站過(guò)卡速度比車(chē)輛到來(lái)的速度慢時(shí),就會(huì)有阻塞現(xiàn)象。
綜合起來(lái)就是:因?yàn)榱坎詈退俣炔?,?dǎo)致阻塞現(xiàn)象。
思考問(wèn)題,為什么會(huì)有量差?
因?yàn)橛行┵Y源是有限的,是很難避免的,高速公路出口區(qū)域的大小有限,收費(fèi)亭的個(gè)數(shù)會(huì)根據(jù)合理的規(guī)劃設(shè)立,即使設(shè)立了1千個(gè)收費(fèi)亭,從高速路到來(lái)的汽車(chē)跑到距離最遠(yuǎn)的那個(gè)收費(fèi)亭也是相當(dāng)遠(yuǎn),沒(méi)有車(chē)主愿意跑那么遠(yuǎn)去收費(fèi),它就形同虛設(shè),有效收費(fèi)亭數(shù)就還是一個(gè)相對(duì)很小的數(shù)量。同時(shí),還需要考慮成本因素。
在程序里,比如數(shù)據(jù)庫(kù)連接池里的連接是有限的,比如10條連接,但1毫秒內(nèi)需要做1000個(gè)查詢(xún),就會(huì)形成阻塞現(xiàn)象。
而速度差是客觀存在的,收費(fèi)亭還需要經(jīng)過(guò)不斷的發(fā)展,才能達(dá)到和高速公路相匹配的速度,但收費(fèi)亭還有一個(gè)作用就是讓高速的車(chē)輛減速下來(lái),去匹配非高速公路的速度。
在程序里,數(shù)據(jù)庫(kù)查詢(xún),需要經(jīng)過(guò)網(wǎng)絡(luò)IO和磁盤(pán)IO,相同的內(nèi)容怎么都比在本機(jī)內(nèi)存中直接檢索出來(lái)要慢。
阻塞,其實(shí)是一個(gè)客觀存在的現(xiàn)象,它本質(zhì)上是沒(méi)法繞開(kāi)的。
既然繞不開(kāi),那……非阻塞又是什么?
非阻塞
還是上面的例子,車(chē)輛經(jīng)過(guò)高速路收費(fèi)亭,非阻塞更像是改版的ETC,車(chē)輛進(jìn)高速,掃一下車(chē)牌登記一下,車(chē)輛離開(kāi)高速,掃一下車(chē)牌登記一下,然后車(chē)輛離開(kāi)了,開(kāi)出個(gè)幾百米后車(chē)主手機(jī)才收到ETC被扣費(fèi)的短信,此時(shí)高速路收費(fèi)才算完成。整個(gè)過(guò)程,停留的時(shí)間很短,如果車(chē)牌識(shí)別效率非常高,甚至可以把車(chē)卡的桿去掉,這樣車(chē)輛就無(wú)需停留。

無(wú)需停留即速度與車(chē)輛到來(lái)速度相匹配,即沒(méi)有阻塞現(xiàn)象。
那是真的沒(méi)有阻塞了嗎?怎么可能,只是從車(chē)的角度來(lái)看,車(chē)確實(shí)不阻塞了,但從整個(gè)收費(fèi)程序來(lái)看,車(chē)輛跑出幾百米后才收費(fèi)成功,就表示實(shí)際上自動(dòng)扣費(fèi)的速度比較慢,阻塞范圍縮小到了自動(dòng)扣費(fèi)上。
把阻塞范圍縮小,縮短主體停留時(shí)間,就是非阻塞要做的事情。
到這里,先記住這個(gè)結(jié)論,先折起一小部分內(nèi)容留最后總結(jié)聯(lián)系上下文……
同步
下班回家到家門(mén)口的時(shí)候,開(kāi)門(mén)經(jīng)過(guò)以下步驟:
- 1.掏鑰匙(還需要從幾百把鑰匙里挑選鑰匙請(qǐng)忽略鑰匙的步驟)
- 2.插入門(mén)鎖孔(磁卡鎖、指紋鎖、人臉鎖等,請(qǐng)積極回憶用鑰匙的日子)
- 3.旋轉(zhuǎn)鑰匙,開(kāi)門(mén)
正常來(lái)說(shuō),三個(gè)步驟是順序依賴(lài)的,這三步驟你怎么換人分著做,都會(huì)等待前一個(gè)步驟完成。
這時(shí)候,如果沒(méi)有別的事情干擾,基本上我們會(huì)一個(gè)人去完成整個(gè)開(kāi)門(mén)的事情,因?yàn)閾Q人,也需要時(shí)間。
開(kāi)門(mén)的人,看作一個(gè)主體;整個(gè)開(kāi)門(mén)過(guò)程,可以看作一個(gè)事務(wù)。那么:
一個(gè)主體獨(dú)自完成一個(gè)事務(wù),便可以認(rèn)為這個(gè)過(guò)程是同步的。
在程序里,給員工張三發(fā)一個(gè)節(jié)日祝福短信,步驟相似:
public static void main(String[] args) {
// 給員工張三發(fā)一個(gè)節(jié)日祝福短信,步驟相似:
// 1. 先把員工張三的信息查找出來(lái)
Employee employee = findEmployee("張三");
// 2. 編輯短信:”祝張三先生節(jié)日快樂(lè),闔家幸福!“
String message = "祝張三" + employee.getGender() + "節(jié)日快樂(lè),闔家幸福!";
// 3. 調(diào)用短信發(fā)送API發(fā)送短信內(nèi)容到員工的手機(jī)號(hào)碼
sendMessage(employee.getPhone(), message);
}
1.先把員工張三的信息查找出來(lái)
2.編輯短信:”祝張三先生節(jié)日快樂(lè),闔家幸福!“
3.調(diào)用短信發(fā)送API發(fā)送短信內(nèi)容到員工的手機(jī)號(hào)碼
整個(gè)事務(wù)都在一條線(xiàn)程里順序完成,則屬于同步操作。
同步的核心,是一個(gè)主體。主要看你把什么定為一個(gè)主體。
異步
接著上面,同步是一個(gè)主體做事,那么異步,就是多個(gè)主體做事。
比如開(kāi)門(mén)的例子,如果把主體具體到手,右手在做開(kāi)門(mén)這些步驟時(shí),左手可能在摘下口罩,這時(shí)候兩件事情都不沖突,摘下口罩后,還可以撓撓頭,抓抓癢,左手可以為所欲為(左手千萬(wàn)別掰斷右手)。
同一時(shí)刻,多個(gè)主體在做事,就屬于異步。
在程序里,線(xiàn)程1給張三發(fā)節(jié)日祝福短信,線(xiàn)程2給李四發(fā)節(jié)日祝福短信,線(xiàn)程3給王五發(fā),完全沒(méi)有問(wèn)題,為所欲為有木有。
當(dāng)然,如果多個(gè)線(xiàn)程在做相同的事情,也可以叫并發(fā)。
思考問(wèn)題,什么時(shí)候建議異步?
當(dāng)多個(gè)事情沒(méi)有沖突,而你又有足夠的資源去同時(shí)展開(kāi)工作時(shí)。
比如邊開(kāi)門(mén)邊撓頭的例子,如果你的左手因?yàn)閿?shù)錢(qián)導(dǎo)致短暫性發(fā)麻無(wú)力,只有右手可以活動(dòng),那么邊開(kāi)門(mén)邊撓頭只會(huì)讓你在切換這兩件事的時(shí)候花費(fèi)更多的時(shí)間。
在代碼里,如果想要給張三同時(shí)發(fā)出去短信和郵件,則可以使用異步的方式去實(shí)現(xiàn):
public static void main(String[] args) {
// 給員工張三發(fā)一個(gè)節(jié)日祝福短信,步驟相似:
// 1. 先把員工張三的信息查找出來(lái)
Employee employee = findEmployee("張三");
// 開(kāi)啟線(xiàn)程2去發(fā)郵件
new Thread(() -> {// 這里邊的就是異步操作
// 編輯郵件
String mailMessage = "祝<h3>張三</h3>" + employee.getGender() + "節(jié)日快樂(lè),闔家幸福!";
// 發(fā)送郵件
sendEmail(employee.getEmail(), mailMessage);
}).start();
// 2. 編輯短信:”祝張三先生節(jié)日快樂(lè),闔家幸福!“
String message = "祝張三" + employee.getGender() + "節(jié)日快樂(lè),闔家幸福!";
// 3. 調(diào)用短信發(fā)送API發(fā)送短信內(nèi)容到員工的手機(jī)號(hào)碼
sendMessage(employee.getPhone(), message);
}
1.先把員工張三的信息查找出來(lái)
2.線(xiàn)程1(main線(xiàn)程):編輯短信;線(xiàn)程2:編輯郵件
3.線(xiàn)程1(main線(xiàn)程):發(fā)送短信;線(xiàn)程2:發(fā)送郵件
線(xiàn)程2在start()后,main線(xiàn)程就可以繼續(xù)往下執(zhí)行了,main線(xiàn)程并不會(huì)等待線(xiàn)程2執(zhí)行完成,也就是說(shuō),異步有一個(gè)特點(diǎn)——非阻塞。
異步可以加上回調(diào)這個(gè)利器,在執(zhí)行出結(jié)果時(shí),通過(guò)回調(diào)的方式,去反饋結(jié)果,這里不展開(kāi)細(xì)談。
總結(jié)
因?yàn)椴糠仲Y源有限,所以阻塞客觀存在的,可以簡(jiǎn)單的理解為有排隊(duì)等待的現(xiàn)象,就是阻塞。
非阻塞主要是把阻塞范圍縮小,或者把可以延遲完成的事情異步完成,縮短主體停留時(shí)間。
最后回到收費(fèi)亭的非阻塞例子,車(chē)輛在經(jīng)過(guò)出高速的收費(fèi)亭登記后,就讓另一條線(xiàn)程去執(zhí)行收費(fèi)操作,并不影響車(chē)輛通行,等車(chē)輛行駛出幾百米后,異步的線(xiàn)程執(zhí)行完畢,短信也發(fā)到了車(chē)主的手機(jī)上。
多加一些思考就能發(fā)現(xiàn),因?yàn)樗俣仁窍鄬?duì)的,阻塞也是相對(duì)的,收費(fèi)亭A的速度慢,但是對(duì)于它自己來(lái)說(shuō),它已經(jīng)是全速了,它沒(méi)停過(guò)就沒(méi)有阻塞,但是高速路到來(lái)B的車(chē)因?yàn)樗O聛?lái)等待了,所以阻塞須有A和B相互參照,才能看出誰(shuí)是瓶頸。
同步和異步,也是相對(duì)的,這取決于主體的粒度,應(yīng)用服務(wù)里A有100條線(xiàn)程在協(xié)同完成任務(wù)X,主體為線(xiàn)程時(shí),他們是異步的,但當(dāng)你把整個(gè)服務(wù)A看作一個(gè)整體時(shí),他是同步的,因?yàn)椴还苣銉?nèi)部有多少線(xiàn)程,你都只是完成了任務(wù)X,僅由一個(gè)主體,完成一個(gè)事務(wù),就是同步。
運(yùn)用這些思維,可以很好的去理解阻塞隊(duì)列、線(xiàn)程池、連接池等組件,以后有空再展開(kāi)吧。
以上就是一篇文章理解阻塞、非阻塞、同步、異步的詳細(xì)內(nèi)容,更多關(guān)于阻塞、非阻塞、同步、異步的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Windows環(huán)境下實(shí)現(xiàn)Jenkins部署的教程詳解
這篇文章主要介紹了Windows環(huán)境下實(shí)現(xiàn)Jenkins部署,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
java asp分析各種搜索引擎的關(guān)鍵字,自動(dòng)識(shí)別url 中關(guān)鍵字的編碼
網(wǎng)上也有一些代碼,大部分都是通過(guò)輸入的關(guān)鍵字來(lái)識(shí)別編碼,并解碼。但是搜索引擎得到的referer來(lái)源地址上的關(guān)鍵字是通過(guò)URLencode編碼過(guò)的,而且各個(gè)網(wǎng)站的關(guān)鍵字Urlencode編碼都不一樣,gbk,utf-8,gb2312等等。2009-01-01
趁熱打鐵!HTTPGet與HTTPPost的區(qū)別詳解
這篇文章主要介紹了趁熱打鐵!HTTPGet與HTTPPost的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
淺析mmdetection在windows10系統(tǒng)環(huán)境中搭建過(guò)程
這篇文章主要介紹了mmdetection在windows10系統(tǒng)環(huán)境中搭建過(guò)程,本文圖文并茂通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01

