国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

并發(fā)的相關(guān)的幾個(gè)疑問(wèn)

2019-11-08 03:26:28
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

緩存一致性問(wèn)題

參考下圖,同一塊主內(nèi)存區(qū)域的值在處理器中多個(gè)處理單元處理了,都同時(shí)寫(xiě)入的時(shí)候,就需要決定是以誰(shuí)的值為準(zhǔn),這個(gè)問(wèn)題就是緩存一致性問(wèn)題解決辦法就是定義一套協(xié)議來(lái)處理,JVM中也有類(lèi)似的協(xié)議來(lái)處理主內(nèi)存與工作內(nèi)存之間緩存一致性問(wèn)題。處理器、高速緩存、主內(nèi)存間的交互關(guān)系線(xiàn)程、主內(nèi)存、工作內(nèi)存三者的交互關(guān)系

JVM緩存一致性問(wèn)題解決協(xié)議?

java內(nèi)存模型中定義了以下8中操作來(lái)完成主內(nèi)存與工作內(nèi)存之間交互的實(shí)現(xiàn)細(xì)節(jié):

1、luck(鎖定):作用于主內(nèi)存的變量,它把一個(gè)變量標(biāo)示為一條線(xiàn)程獨(dú)占的狀態(tài)。

2、unlock(解鎖):作用于主內(nèi)存的變量,它把一個(gè)處于鎖定狀態(tài)的變量釋放出來(lái),釋放后的變量才可以被其他線(xiàn)程鎖定。

3、read(讀取):作用于主內(nèi)存的變量,它把一個(gè)變量的值從主內(nèi)存?zhèn)鬏數(shù)焦ぷ鲀?nèi)存中,以便隨后的load動(dòng)作使用。

4、load(載入):作用于工作內(nèi)存的變量,它把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中。

5、use(使用):作用于工作內(nèi)存的變量,它把工作內(nèi)存中的一個(gè)變量的值傳遞給執(zhí)行引擎,每當(dāng)虛擬機(jī)遇到一個(gè)需要使用到變量的值得字節(jié)碼指令時(shí)將會(huì)執(zhí)行這個(gè)操作。

6、assign(賦值):作用于工作內(nèi)存的變量,它把一個(gè)從執(zhí)行引擎接收到的值賦給工作內(nèi)存的變量,每當(dāng)虛擬機(jī)遇到一個(gè)給變量賦值的字節(jié)碼指令時(shí)執(zhí)行這個(gè)操作。

7、store(存儲(chǔ)):作用于工作內(nèi)存的變量,它把工作內(nèi)存中的一個(gè)變量的值傳遞到主內(nèi)存中,以便隨后的write操作使用。

8、write(寫(xiě)入):作用于主內(nèi)存的變量,它把store操作從工作內(nèi)存中得到的變量值放入主內(nèi)存的變量中。

Java內(nèi)存模型還規(guī)定了執(zhí)行上述8種基本操作時(shí)必須滿(mǎn)足如下規(guī)則:

1、不允許read和load、store和write操作之一單獨(dú)出現(xiàn),以上兩個(gè)操作必須按順序執(zhí)行,但沒(méi)有保證必須連續(xù)執(zhí)行,也就是說(shuō),read與load之間、store與write之間是可插入其他指令的。

2、不允許一個(gè)線(xiàn)程丟棄它的最近的assign操作,即變量在工作內(nèi)存中改變了之后必須把該變化同步回主內(nèi)存。

3、不允許一個(gè)線(xiàn)程無(wú)原因地(沒(méi)有發(fā)生過(guò)任何assign操作)把數(shù)據(jù)從線(xiàn)程的工作內(nèi)存同步回主內(nèi)存中。

4、一個(gè)新的變量只能從主內(nèi)存中“誕生”,不允許在工作內(nèi)存中直接使用一個(gè)未被初始化(load或assign)的變量,換句話(huà)說(shuō)就是對(duì)一個(gè)變量實(shí)施use和store操作之前,必須先執(zhí)行過(guò)了assign和load操作。

5、一個(gè)變量在同一個(gè)時(shí)刻只允許一條線(xiàn)程對(duì)其執(zhí)行l(wèi)ock操作,但lock操作可以被同一個(gè)條線(xiàn)程重復(fù)執(zhí)行多次,多次執(zhí)行l(wèi)ock后,只有執(zhí)行相同次數(shù)的unlock操作,變量才會(huì)被解鎖。

6、如果對(duì)一個(gè)變量執(zhí)行l(wèi)ock操作,將會(huì)清空工作內(nèi)存中此變量的值,在執(zhí)行引擎使用這個(gè)變量前,需要重新執(zhí)行l(wèi)oad或assign操作初始化變量的值。

7、如果一個(gè)變量實(shí)現(xiàn)沒(méi)有被lock操作鎖定,則不允許對(duì)它執(zhí)行unlock操作,也不允許去unlock一個(gè)被其他線(xiàn)程鎖定的變量。

8、對(duì)一個(gè)變量執(zhí)行unlock操作之前,必須先把此變量同步回主內(nèi)存(執(zhí)行store和write操作)。

先行發(fā)生原則

程序次序規(guī)則(PRogram Order Rule):在一個(gè)線(xiàn)程中,按照程序代碼順序,書(shū)寫(xiě)在前面的代碼操作先行發(fā)生于后面的操作

管程鎖定規(guī)則(Monitor Lock Rule):一個(gè) unlock 操作先行發(fā)生于后面對(duì)同一個(gè)鎖的 lock 操作。“后面”指的是時(shí)間的先后順序。

volatile 變量規(guī)則(Volatile Variable Rule):對(duì)一個(gè) volatile 變量的寫(xiě)操作先行發(fā)生于后面對(duì)這個(gè)變量的讀操作。“后面”指的是時(shí)間的先后順序。

線(xiàn)程啟動(dòng)規(guī)則(Thread Start Rule):Thread 對(duì)象的 start() 方法先行發(fā)生于此線(xiàn)程的每一個(gè)動(dòng)作。

線(xiàn)程終止規(guī)則(Thread Termination Rule):線(xiàn)程中所有操作先行發(fā)生于對(duì)此線(xiàn)程的終止檢測(cè)。

線(xiàn)程中斷規(guī)則(Thread Interruption Rule):對(duì)線(xiàn)程 interrupt() 方法的調(diào)用先行發(fā)生于代碼檢測(cè)到中斷事件的發(fā)生。

對(duì)象終結(jié)規(guī)則(Finalizer Rule):一個(gè)對(duì)象的初始化完成(構(gòu)造函數(shù)結(jié)束)先行發(fā)生于它的 finalize() 方法的開(kāi)始。

傳遞性(Transitivity):如果操作A先行發(fā)生于操作B,操作B先行發(fā)生于操作C,那么操作A先行發(fā)生于操作C。

時(shí)間的先后與先行發(fā)生原則并沒(méi)有太多關(guān)系

volatile變量的特點(diǎn)

1、保證可見(jiàn)性,也就是說(shuō)對(duì)volatile變量進(jìn)行寫(xiě)入操作的時(shí)候,其它線(xiàn)程能立即看到變化,而普通變量是做不到的。實(shí)現(xiàn)的原理就是volatile變量每次使用前都會(huì)去刷新,而每次寫(xiě)入都會(huì)實(shí)時(shí)同步到主內(nèi)存中。

2、volatile變量并不是并發(fā)安全的,雖然我們能立即看到volatile變量的最新值,但volatile變量參與的運(yùn)算,并不是一個(gè)原子操作。

volatile變量適用的場(chǎng)景就是一個(gè)控制線(xiàn)程操作,其它work線(xiàn)程依賴(lài)它來(lái)進(jìn)行決策,這種情況下不需要用鎖就能實(shí)現(xiàn)并發(fā)安全的效果

原子類(lèi)的實(shí)現(xiàn)基礎(chǔ)

硬件支持的組合原子指令(CAS)是實(shí)現(xiàn)基礎(chǔ),如:

測(cè)試并設(shè)置; 

獲取并增加; 

交換; 

比較并交換; 

加載鏈條/條件存儲(chǔ);

線(xiàn)程安全的分類(lèi)

1、不可變;例如final對(duì)象或者屬性,如果在初使化過(guò)程中沒(méi)有this引用的逃逸,初始完成后,就一定是線(xiàn)程安全的;2、絕對(duì)線(xiàn)程安全;不需要任何外加輔助,類(lèi)本身就能實(shí)現(xiàn)完全的線(xiàn)程安全訪問(wèn),則認(rèn)為這種類(lèi)是絕對(duì)線(xiàn)程安全的;3、相對(duì)線(xiàn)程安全;單個(gè)方法的調(diào)用是安全的,但是如果涉及到多個(gè)方法的調(diào)用,則不一定能保證線(xiàn)程安全的;jdk里邊提供的很多系統(tǒng)類(lèi),如vector、HashTable、StringBuilder等,都是簡(jiǎn)單的在單個(gè)方法上加syncronized加實(shí)現(xiàn)安全,所以都只能保證單個(gè)方法的安全,是典型的相對(duì)線(xiàn)程安全類(lèi)。4、線(xiàn)程兼容;通過(guò)輔助工具,如加鎖,可以實(shí)現(xiàn)線(xiàn)程安全的類(lèi),就是線(xiàn)程兼容;5、線(xiàn)程對(duì)立;無(wú)論如何都無(wú)法實(shí)現(xiàn)線(xiàn)程安全。

線(xiàn)程安全的實(shí)現(xiàn)方法

1、互斥同步;典型就是使用syncronized以及java.util.concurrent包里邊的ReentrantLock;因?yàn)樾枰€(xiàn)程阻塞,也叫做阻塞式同步;2、非阻塞同步;不需要線(xiàn)程阻塞,相比阻塞鎖是悲觀鎖,這個(gè)是樂(lè)觀鎖,比如說(shuō)原子類(lèi)就都是非阻塞同步,實(shí)現(xiàn)的基礎(chǔ)是硬件支持的組合原子指令;3、無(wú)同步方案;如可重入代碼(例如不引用共享數(shù)據(jù)的局部方法)、線(xiàn)程本地存儲(chǔ)(thread local storage)

鎖優(yōu)化的常用手段有哪些?

鎖作為最常用保證線(xiàn)程安全的工具,用的不好會(huì)導(dǎo)致死鎖,或者本來(lái)可以并發(fā)的變成了串行,降低了執(zhí)行效率。

死鎖問(wèn)題靠的是編碼邏輯實(shí)現(xiàn)的謹(jǐn)慎,而鎖的優(yōu)化,則能大大的降低鎖對(duì)程序效率的影響。

1、自旋鎖與自適應(yīng)自旋;

   不讓出對(duì)CPU的占用時(shí)間,而是循環(huán)等待獲得對(duì)應(yīng)的鎖。如果鎖占用時(shí)間很短,自旋等待的效果就會(huì)非常好;反之,如果鎖被占用的時(shí)間特別長(zhǎng),那么自旋的線(xiàn)程只會(huì)白白的浪費(fèi)處理器資源,而不會(huì)做任何有用的工作,反而會(huì)帶來(lái)性能上的浪費(fèi);我的理解是如果自旋的時(shí)間比線(xiàn)程上下文切換的代價(jià)還要大,就不如直接阻塞而不是自旋了。

2、鎖消除;

虛擬機(jī)檢測(cè)到一段代碼上不存在共享數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題,就會(huì)把鎖消除;

3、鎖粗化;

一般我們是盡量把鎖的范圍減小。但是有時(shí)候反其道而行之也能提高效率,在一段代碼中反復(fù)對(duì)同一個(gè)鎖加鎖解鎖,就可以直接對(duì)整塊代碼加鎖,以減少操作鎖的開(kāi)銷(xiāo);

4、輕量級(jí)鎖;

5、偏向鎖;


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 福海县| 册亨县| 卓尼县| 民丰县| 东宁县| 庆城县| 大同县| 筠连县| 汕头市| 鄂伦春自治旗| 喀喇沁旗| 永嘉县| 蒙山县| 屯门区| 普陀区| 高清| 丹江口市| 扶绥县| 石渠县| 黎平县| 蒙山县| 津南区| 尉氏县| 万年县| 扬州市| 诸城市| 犍为县| 榆树市| 通河县| 久治县| 连平县| 海南省| 龙口市| 社会| 南召县| 兴义市| 吉林省| 卢龙县| 平塘县| 宁陕县| 桓台县|