基本概念
并行和并發(fā)的區(qū)別
并行(parallel)
同時(shí)做某些事情,可以互不干擾的同時(shí)做幾件事。
舉例:高速公路的車(chē)道,雙向4車(chē)道,所有車(chē)輛(數(shù)據(jù))可以互不干擾的在自己的車(chē)道上奔跑 (傳輸)。
在同一個(gè)時(shí)刻,每條車(chē)道上可能同時(shí)有車(chē)輛在跑,是同時(shí)發(fā)生的概念。
如下圖所示,在t時(shí)刻可以有多個(gè)程序在執(zhí)行中,這樣就稱(chēng)作并行。(注意是同一時(shí)刻,不是同一個(gè)時(shí)間段)

并發(fā),(concurrency)
也是同時(shí)做某些事,但是強(qiáng)調(diào),同一個(gè)時(shí)段做幾件事
鄉(xiāng)村公路一條車(chē)道,半幅路面出現(xiàn)了坑,交警指揮車(chē)輛走另外半幅路面,一個(gè)方向放行3分鐘,
停止方向,換另一個(gè)方向放行。發(fā)生了車(chē)輛同時(shí)要通過(guò)路面的事件,這就是并發(fā)。
如下圖所示,在T時(shí)間段內(nèi)可以有多個(gè)程序在執(zhí)行中,這樣就稱(chēng)作并發(fā)。(注意是同一時(shí)間段,一般這個(gè)時(shí)間段都指的是一個(gè)比較小的時(shí)間段,不是同一個(gè)時(shí)刻)

經(jīng)典的生產(chǎn)者和消費(fèi)者模型
比如有這樣一個(gè)生產(chǎn)者:一個(gè)賣(mài)煎餅果子的老奶奶,在沒(méi)有人買(mǎi)的時(shí)候可多做出幾個(gè)讓后放在架子上,但是架子上的容量是有限的,比如最多能放10個(gè),當(dāng)老奶奶想空余的時(shí)間多做出幾個(gè)放在架子上的時(shí)候每次都要看一看架子上有沒(méi)有空余的空間來(lái)放做出來(lái)的煎餅果子。
比如有這樣的消費(fèi)者:很多喜歡吃煎餅果子的小姐姐,都喜歡到老奶奶這里來(lái)買(mǎi)煎餅果子,如果小姐姐來(lái)的早,在架子上有很多已經(jīng)做好了的煎餅果子,然后小姐姐只要一來(lái),看一看架子上是否有做好了的煎餅果子,如果有就直接就買(mǎi)上走人了,但是晚來(lái)的小哥哥就沒(méi)有那么運(yùn)氣好了,當(dāng)他來(lái)的時(shí)候架子上沒(méi)有了,只有等待著老奶奶做好了再賣(mài)給他。
并發(fā)的解決
舉例“食堂打飯”:
很多人都肯定經(jīng)歷過(guò),中午12點(diǎn),下課后一望無(wú)際的腦袋都涌向食堂,(一小撮吃外賣(mài)的不算,并不是很多人家里都富有,我也是只有吃食堂的份了)。特別是在12:00--12:30這個(gè)時(shí)間段人流量是最大的,這就叫做高并發(fā)。為了使得食堂不會(huì)因?yàn)槲覀內(nèi)藬?shù)太多了供應(yīng)不過(guò)來(lái),崩掉了。所以食堂就要求我們排隊(duì),這就相當(dāng)于我們程序的消息隊(duì)列了,使用隊(duì)列的方式是一個(gè)可以解決并發(fā)的一種方法,雖然這種方法不一定很好,但是這是解決并發(fā)的一種方法。
所以第一種解決辦法就是:隊(duì)列、緩沖區(qū):
其實(shí)在食堂的打飯窗口前都有大片用來(lái)排隊(duì)的區(qū)域,這樣一個(gè)容納學(xué)生的區(qū)域就叫做緩沖區(qū),也就是在程序中暫時(shí)存放數(shù)據(jù)的地方。
緩沖區(qū)技術(shù)最開(kāi)始提出來(lái)是用在處理內(nèi)存和CPU的速度問(wèn)題的,大家都知道內(nèi)存讀寫(xiě)很快,但是我們CPU的計(jì)算能力更是日益更加的強(qiáng)大,就出現(xiàn)了,內(nèi)存的讀寫(xiě)數(shù)據(jù)跟不上CPU的處理數(shù)據(jù),然后人們就發(fā)明了cache(緩存),CPU在處理數(shù)據(jù)的時(shí)候先把數(shù)據(jù)放入IO數(shù)據(jù)更快的cache中,然后再進(jìn)行處理,也可以理解成,cache就是一個(gè)數(shù)據(jù)臨時(shí)存放的地方,一般的計(jì)算機(jī)中都有多級(jí)緩存,CPU中一般也有cache,CPU中的cache一般稱(chēng)作片內(nèi)cahe。
優(yōu)先隊(duì)列
假設(shè)今天是女神節(jié),學(xué)校為了給學(xué)校的女神們過(guò)節(jié)日,然后就出現(xiàn)了這樣一個(gè)規(guī)則,只要有女生來(lái)打飯就直接去最前面,不用跟在男生后面進(jìn)行排隊(duì)。這樣的一個(gè)隊(duì)列,在編程中就叫做優(yōu)先隊(duì)列。
但是作為一個(gè)理工科大學(xué),女生還是寥寥無(wú)幾。
這種優(yōu)先隊(duì)列的方式還是不太好,還有什么其他的方法呢?
我們可以這樣思考,比如我們?nèi)ナ程么蝻垼缓蟛慌抨?duì)了,直接就往里面沖,但是我們注意的是總有人先去到窗口里面,每個(gè)打飯的阿姨都只能給一個(gè)打飯的同學(xué)服務(wù)。也可以叫做這個(gè)同學(xué)把這樣阿姨占用了,在我們編程里面,當(dāng)你去請(qǐng)求一個(gè)資源的時(shí)候,如果你動(dòng)作夠快,然后占用了這個(gè)資源,然后就把這個(gè)資源給鎖上了。
所以第二種解決辦法就是:爭(zhēng)搶、鎖資源:
但是這樣方法也不是很好,比如:有的同學(xué)為了搶著先打飯,甚至爭(zhēng)的鼻青臉腫的。也比如說(shuō)某個(gè)中學(xué)占用了一個(gè)打飯的阿姨,但是他在哪里想了一半天都沒(méi)有想好吃什么,后面判斷的同學(xué)就一直在后面等著,最后都爭(zhēng)吵起來(lái)了。還有一種情況就是比如某個(gè)同學(xué)平時(shí)也不鍛煉,身體素質(zhì)很差,更本就搶不贏其他的同學(xué)。(在Linux內(nèi)核中其實(shí)也是這種爭(zhēng)搶機(jī)制,比如我們?nèi)祟?lèi)的社會(huì),如果你太弱就搶不贏別人,最后物競(jìng)天擇……,所以我們要努力學(xué)習(xí),增強(qiáng)自己。)
雖然爭(zhēng)搶式的方式有很多的問(wèn)題,但是我們也不能只看缺點(diǎn),同時(shí)爭(zhēng)搶式也有優(yōu)點(diǎn),比如:比如可以激勵(lì)我們的同學(xué)節(jié)省打飯的時(shí)間。
這學(xué)期我們學(xué)校的一個(gè)食堂就升級(jí)了,以前是同學(xué)們走到打飯的窗口前面,要吃什么然后再叫阿姨打,但是這樣效率并不是很高。所以這學(xué)期就換成了這樣的機(jī)制,阿姨們提前把飯和菜提前用小點(diǎn)的碗和盤(pán)子盛好,然后同學(xué)們走到窗口前面就只要看著自己喜歡的菜和飯,端著就走了,到另外的地方買(mǎi)單就好。
所以第三種解決辦法就是:預(yù)處理:
預(yù)處理的核心思想就是提前準(zhǔn)備好用戶(hù)請(qǐng)求的資源。這不失為一個(gè)好的辦法。
另外比如學(xué)校因?yàn)檎械搅撕芏嗟男律?,食堂常常是人滿(mǎn)為患,所以學(xué)校就準(zhǔn)備擴(kuò)建了。另外又修了一棟樓來(lái)開(kāi)食堂。導(dǎo)致打飯的窗口也變多了,但是這樣花費(fèi)就大了,如果學(xué)校沒(méi)有這樣的積蓄是蓋不起大樓的。
所以第四種解決辦法就是:并行:
比如我們最以前的8086芯片就只是單核心的,現(xiàn)在都是多核心的,處理的速度自然就提升了上來(lái),比如打飯的窗口多了,同學(xué)們打到飯的速度也就變快了。
后面又接著分析,食堂的阿姨因?yàn)楣ぷ鞑环e極,或者說(shuō)是業(yè)務(wù)能力不行,打飯的動(dòng)作太慢了,出現(xiàn)了這種情況怎么辦呢,也就有解雇,然后招聘能力更好的打飯的阿姨了。
所以第五種解決辦法就是:提速:
這種提速就是更換新的東西,比如我們電腦運(yùn)行速度越來(lái)越卡了,所以也就只用換更好的CPU,速度更快的內(nèi)存。但是這種提升比較不常用,比如:我們現(xiàn)在就算你高薪請(qǐng)一個(gè)能力很強(qiáng)的阿姨但是,人重視要累的,所以這種提升是有上限的。
我們應(yīng)該在坐飛機(jī)或者坐火車(chē)的時(shí)候,常常在安檢的時(shí)候地方前面有個(gè)很長(zhǎng)的用鐵欄桿為其他的走廊,我們所有要過(guò)安檢的人先從這個(gè)走廊中依次排隊(duì)進(jìn)入,當(dāng)排完隊(duì)后,后面就可以進(jìn)入到各個(gè)安檢口,檢查身體和行李了。
所以第六種解決辦法就是:消息中間件:
常見(jiàn)的消息中間件有RabbitMQ、ActiveMQ ( Apache )、RocketMQ (阿里Apache )、kafka ( Apache )等。
當(dāng)然還有其他手段解決并發(fā)問(wèn)題,但是已經(jīng)列舉除了最常用的解決方案,一般來(lái)說(shuō)不同的并發(fā)場(chǎng)景用不同的策略,而策略可能是多種方式的優(yōu)化組合。
可能有的人無(wú)法區(qū)分上面我講的,消息隊(duì)列和消息中間件,這兩種方法的區(qū)別,其實(shí)這兩種本質(zhì)上都是消息隊(duì)列的機(jī)制,只是前一種是在我服務(wù)的內(nèi)部實(shí)現(xiàn),二后一種是在服務(wù)的外部實(shí)現(xiàn)