卖逼视频免费看片|狼人就干网中文字慕|成人av影院导航|人妻少妇精品无码专区二区妖婧|亚洲丝袜视频玖玖|一区二区免费中文|日本高清无码一区|国产91无码小说|国产黄片子视频91sese日韩|免费高清无码成人网站入口

spring框架 為什么在多核多線程程序中要慎用volatile關(guān)鍵字?

為什么在多核多線程程序中要慎用volatile關(guān)鍵字?由于volatile不能保證它的原子性,它只能保證一個(gè)線程在修改后對(duì)其他線程可見(jiàn),特別是當(dāng)多個(gè)線程自動(dòng)激活并減少一個(gè)變量時(shí),會(huì)導(dǎo)致變量錯(cuò)誤。參考《

為什么在多核多線程程序中要慎用volatile關(guān)鍵字?

由于volatile不能保證它的原子性,它只能保證一個(gè)線程在修改后對(duì)其他線程可見(jiàn),特別是當(dāng)多個(gè)線程自動(dòng)激活并減少一個(gè)變量時(shí),會(huì)導(dǎo)致變量錯(cuò)誤。參考《深入理解Java虛擬機(jī)》一書(shū),volatile用于以下場(chǎng)景:

1>操作結(jié)果不依賴于變量的當(dāng)前值,或者可以確保只有一個(gè)線程修改變量的值。

2>變量不需要與其他狀態(tài)變量一起參與不變約束。因此,在使用volatile關(guān)鍵字時(shí),應(yīng)該小心。不僅僅是簡(jiǎn)單的類(lèi)型變量被volatile修改。此變量上的所有操作都是原始操作。當(dāng)一個(gè)變量的值由它以前的值決定時(shí),例如n=n1,n volatile關(guān)鍵字將無(wú)效。只有當(dāng)一個(gè)變量的值與其前一個(gè)值無(wú)關(guān)時(shí),對(duì)該變量的操作才能是原子級(jí)的,例如n=m1,這是原始級(jí)別。因此,在使用volatile鍵時(shí)必須小心。如果不確定,可以使用synchronized而不是volatile。

為什么在多核多線程程序中要慎用volatile關(guān)鍵字?

一般來(lái)說(shuō),volatile關(guān)鍵字有兩個(gè)用途:一個(gè)用于處理ISO C/C中的“異?!眱?nèi)存行為(此用途僅保證編譯器不會(huì)進(jìn)行任何優(yōu)化,并且對(duì)多核CPU是否會(huì)無(wú)序優(yōu)化沒(méi)有約束力),另一個(gè)用于Java/中。Net(包括visualbasic)Studio)實(shí)現(xiàn)高性能并行算法(這種使用通過(guò)內(nèi)存屏障保證CPU/編譯器的有序性,通過(guò)JVM或CLR保證易失變量讀寫(xiě)操作的原子性)??傊?,volatile對(duì)于多線程編程是非常危險(xiǎn)的。當(dāng)您使用它時(shí),您必須小心您的代碼是否以您想要的方式在多核上執(zhí)行,特別是對(duì)于尚未引入內(nèi)存模型的C/C程序。為了安全起見(jiàn),我們?nèi)匀皇褂胮thread,Java.util.concurrent文件TBB等并行庫(kù)提供了lock/spinlock、條件變量、barrier、原子變量等同步方法來(lái)很好的工作,因?yàn)樗鼈兊膬?nèi)部實(shí)現(xiàn)調(diào)用了相應(yīng)的內(nèi)存barrier來(lái)保證內(nèi)存的有序性。你只需要確保你的多線程程序沒(méi)有數(shù)據(jù)是的,pthreads庫(kù)也有自己的內(nèi)存模型,但是它的內(nèi)存模型有一些缺點(diǎn),所以直接將多線程內(nèi)存模型集成到C/C中是一個(gè)更好的方法,這也是將來(lái)的趨勢(shì),而不是在volatile中添加獲取和釋放語(yǔ)義關(guān)鍵字,如Java/。Net中,我們將提供另一種具有同步語(yǔ)義的原子變量。如果要實(shí)現(xiàn)更高性能的無(wú)鎖算法,或者使用volatile進(jìn)行同步,首先需要了解CPU的內(nèi)存模型和編程語(yǔ)言,然后時(shí)刻注意原子性和有序性是否得到保證。(注意:沒(méi)有acquire/release語(yǔ)義的情況下使用volatile變量進(jìn)行同步是錯(cuò)誤的,但是您仍然可以在C/C中使用volatile來(lái)修改一個(gè)不用于同步的變量(例如事件),它只是一個(gè)由不同線程讀寫(xiě)的共享變量,但當(dāng)它的新值可以被另一個(gè)線程讀取時(shí),就不能保證了。您需要自己做相應(yīng)的處理)

多個(gè)線程可以讀一個(gè)變量,只有一個(gè)線程可以對(duì)這個(gè)變量進(jìn)行寫(xiě),到底要不要加鎖?

下面簡(jiǎn)要解釋一下原因:

鎖定是因?yàn)椴僮鞑皇窃拥摹W屛覀儼盐业氖中g(shù)作為一個(gè)解釋。參見(jiàn)下面兩個(gè)圖。

我這個(gè)操作需要

看上面的第二個(gè)圖,你能很清楚地理解這個(gè)過(guò)程嗎?

鎖定是為了確保上述三個(gè)步驟是原子操作。

回到問(wèn)題上來(lái),只有一個(gè)線程要寫(xiě),沒(méi)有競(jìng)爭(zhēng),所以不需要鎖定。

但是,如果你看第一張圖片,因?yàn)橹鲀?nèi)存和本地內(nèi)存的存在

在一個(gè)線程寫(xiě)入后,其他線程無(wú)法立即看到它。這就是可見(jiàn)性問(wèn)題。

添加volatile關(guān)鍵字后,它將在操作后強(qiáng)制工作內(nèi)存和主內(nèi)存同步,以確保其他線程可以立即看到它。

volatile關(guān)鍵字在Java中有什么作用?

Volatile是為了防止指令重新排序以確??梢?jiàn)性

對(duì)于JVM級(jí)別,是為了防止編譯器重新排序

同時(shí),對(duì)于某些CPU,它們會(huì)通過(guò)緩存鎖或線程來(lái)解決緩存可見(jiàn)性

但是,目前很多CPU已經(jīng)過(guò)優(yōu)化,由于cache一致性MESI會(huì)帶來(lái)性能開(kāi)銷(xiāo),因此采用storebuffer機(jī)制進(jìn)行異步處理,這種機(jī)制會(huì)導(dǎo)致指令的無(wú)序執(zhí)行。這會(huì)導(dǎo)致可見(jiàn)性問(wèn)題。

然后volatile將在CPU級(jí)別增加內(nèi)存屏障,以解決由CPU無(wú)序執(zhí)行引起的可見(jiàn)性問(wèn)題