日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
線程的麻煩事兒,Actor能解決嗎?

馮諾伊曼體系中, CPU和內(nèi)存居于核心的地位。

創(chuàng)新互聯(lián)建站提供高防主機(jī)、云服務(wù)器、香港服務(wù)器、德陽(yáng)機(jī)房服務(wù)器托管

內(nèi)存就像一個(gè)個(gè)的小格子,其中保存著程序要讀寫(xiě)的值。

當(dāng)只有一個(gè)線程來(lái)訪問(wèn)內(nèi)存的時(shí)候,事情非常簡(jiǎn)單:

但是,當(dāng)出現(xiàn)多線程的時(shí)候,就可能會(huì)出現(xiàn)互相覆蓋的危險(xiǎn):

在多線程并發(fā)執(zhí)行的情況下,為了得到正確的結(jié)果,必須要加鎖。

看起來(lái)加鎖是一件輕松的事情, 但實(shí)際上并非如此, 讓我們看一個(gè)轉(zhuǎn)賬的例子:有兩個(gè)賬戶,賬戶A和賬戶B, 現(xiàn)在有一個(gè)線程1,要從賬戶A給賬戶B轉(zhuǎn)50元。

為了防止別的線程并發(fā)操作,相互覆蓋,它需要加鎖:

看起來(lái)沒(méi)有任何問(wèn)題, 但是如果還有個(gè)線程,同時(shí)要從賬戶B 給賬戶A轉(zhuǎn)30元,它也采用了類似的加鎖辦法,就出問(wèn)題了:

有個(gè)非常簡(jiǎn)單的辦法來(lái)解決這個(gè)問(wèn)題:對(duì)賬戶按次序加鎖 。例如所有線程都是先對(duì)賬戶A加鎖,然后對(duì)賬戶B加鎖,這樣死鎖消除了。

看到了吧,多線程并發(fā)編程一不留神就會(huì)出錯(cuò)。

你以為多線程編程是這樣:

實(shí)際上寫(xiě)出的程序是這樣:

而CPU利用率很可能是“一核有難,眾核圍觀”

鎖這么麻煩,能不能不用鎖?

換個(gè)思路,不把賬戶余額看成是簡(jiǎn)單的值,而是一個(gè)黑盒子對(duì)象:

在這個(gè)黑盒子中,保存了賬戶的余額200。

你想存款了,就發(fā)一個(gè)存款的消息過(guò)來(lái),想取款就發(fā)一個(gè)取款的消息過(guò)來(lái),發(fā)完消息就可以撤離了(異步操作)。

不管是有一個(gè)消息,還是有100個(gè)消息,統(tǒng)統(tǒng)放到黑盒子的一個(gè)隊(duì)列中,然后讓Account這個(gè)黑盒子一個(gè)個(gè)順序處理, 對(duì)余額進(jìn)行增加或減少。

外界無(wú)法看到余額,只能通過(guò)消息和這個(gè)黑盒子交互,黑盒子內(nèi)部順序處理,自然不用加鎖。

這個(gè)黑盒子,就是Actor。

試一試用Actor方式來(lái)實(shí)現(xiàn)轉(zhuǎn)賬, 看看和之前有什么不同:

“轉(zhuǎn)賬 Actor” 收到轉(zhuǎn)賬50元的消息, 向賬戶A發(fā)送取出50元的消息, 向賬戶B發(fā)出存入50元的消息。

然后賬戶A 和 賬戶B 收到消息,進(jìn)行處理。

非常清晰,根本不用鎖, 每個(gè)Actor都是獨(dú)立的個(gè)體,它們之間靠消息交互就行了。

可是,在轉(zhuǎn)賬過(guò)程中,如果有別的線程對(duì)賬戶A也做了操作,導(dǎo)致賬戶A余額不足,拋出了異常, 但是賬戶B繼續(xù)存入50元,那這個(gè)轉(zhuǎn)賬其實(shí)就出錯(cuò)了!

這時(shí)候,我們想到了什么?對(duì),就是事務(wù)的原子性:要么不做,要么全做。

所以需要讓這些Actor支持事務(wù),這可真是有點(diǎn)麻煩,因?yàn)锳ctor之間是獨(dú)立的,消息的發(fā)送是異步的,現(xiàn)在轉(zhuǎn)賬卻要求存入和取出兩個(gè)操作需要同步進(jìn)行,并且滿足原子性。

世界上果然沒(méi)有免費(fèi)的午餐。

這里邊要解決兩個(gè)問(wèn)題:

1. 賬戶A和賬戶B的Actor 需要互相等待,直到存入和取出的操作都完成,有任何一個(gè)沒(méi)完成(如拋出異常),就要回滾。

2. 由于消息發(fā)送都是異步的,在執(zhí)行一個(gè)事務(wù)的時(shí)候,可能有其他消息放入消息隊(duì)列,并且被處理,賬戶A和賬戶B的余額不斷地被改變,需要處理這種不斷變化的情況。

可以參考下大名鼎鼎的CAS的原理,每個(gè)事務(wù)開(kāi)始的時(shí)候,記錄下原始的值,在提交的時(shí)候和當(dāng)前值進(jìn)行比較,如果相同,表示在這段時(shí)間內(nèi)沒(méi)有修改,提交成功。否則,讀取當(dāng)前的值,重做事務(wù)中的操作:

沒(méi)有加鎖,就是不斷地在嘗試,由于數(shù)據(jù)都是在內(nèi)存中操作,頻繁地嘗試也不是什么大問(wèn)題(在并發(fā)沖突不是很激烈的情況下)

用這種方式實(shí)現(xiàn)的事務(wù), 做軟件事務(wù)內(nèi)存(Software Transactional Memory),簡(jiǎn)稱STM。

總結(jié)一下,Actor看起來(lái)簡(jiǎn)單,對(duì)于單個(gè)賬戶操作來(lái)說(shuō),是個(gè)很美妙的模型,因?yàn)橘~戶之間是隔離的。 但是對(duì)于一致性要求比較高的場(chǎng)景,如轉(zhuǎn)賬,Actor模型就顯得有些笨拙了。

【本文為專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)作者微信公眾號(hào)coderising獲取授權(quán)】


網(wǎng)頁(yè)題目:線程的麻煩事兒,Actor能解決嗎?
本文來(lái)源:http://www.5511xx.com/article/dpcjjcg.html