摘要:線程切換帶來的原子性問題我們把一個或者多個操作在執(zhí)行的過程中不被中斷的特性稱為原子性。編譯優(yōu)化帶來的有序性問題顧名思義,有序性指的是程序按照代碼的先后順序執(zhí)行。
緩存導(dǎo)致的可見性問題
一個線程對共享變量的修改,另外一個線程能夠立刻看到,稱為可見性
在多核下,多個線程同時修改一個共享變量時,如++操作,每個線程操作的CPU緩存寫入內(nèi)存的時機(jī)是不確定的。除非你調(diào)用CPU相關(guān)指令強(qiáng)刷。
線程切換帶來的原子性問題我們把一個或者多個操作在CPU執(zhí)行的過程中不被中斷的特性稱為原子性。
高級語言里一條語句往往需要多條CPU指令完成。例如count += 1,至少需要三條CPU指令:
指令1:首先,需要把變量count從內(nèi)存加載到CPU的寄存器;
指令2:之后,在寄存器中執(zhí)行+1操作;
指令3:最后,將結(jié)果寫入內(nèi)存(緩存機(jī)制導(dǎo)致可能寫入的是CPU緩存而不是內(nèi)存)。
操作系統(tǒng)做任務(wù)切換,可以發(fā)生在任何一條CPU指令執(zhí)行完,而不是高級語言里的一條語句。
編譯優(yōu)化帶來的有序性問題顧名思義,有序性指的是程序按照代碼的先后順序執(zhí)行。
public class Singleton { static Singleton instance; static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; } }
在new操作上,我們以為 的new操作應(yīng)該是:
分配一塊內(nèi)存M;
在內(nèi)存M上初始化Singleton對象;
然后M的地址賦值給instance變量。
但是實際上優(yōu)化后的執(zhí)行路徑卻是這樣的:
分配一塊內(nèi)存M;
將M的地址賦值給instance變量;
最后在內(nèi)存M上初始化Singleton對象。
優(yōu)化后會導(dǎo)致什么問題呢?我們假設(shè)線程A先執(zhí)行g(shù)etInstance()方法,當(dāng)執(zhí)行完指令2時恰好發(fā)生了線程切換,切換到了線程B 上;如果此時線程B也執(zhí)行g(shù)etInstance()方法,那么線程B在執(zhí)行第一個判斷時會發(fā)現(xiàn) instance != null ,所以直接返回 instance,而此時的instance是沒有初始化過的,如果我們這個時候訪問 instance 的成員變量就可能觸發(fā)空指針異常。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/74998.html
摘要:有可能一個線程中的動作相對于另一個線程出現(xiàn)亂序。當(dāng)實際輸出取決于線程交錯的結(jié)果時,這種情況被稱為競爭條件。這里的問題在于代碼塊不是原子性的,而且實例的變化對別的線程不可見。這種不能同時在多個線程上執(zhí)行的部分被稱為關(guān)鍵部分。 為什么要額外寫一篇文章來研究volatile呢?是因為這可能是并發(fā)中最令人困惑以及最被誤解的結(jié)構(gòu)。我看過不少解釋volatile的博客,但是大多數(shù)要么不完整,要么難...
摘要:因為管理人員是了解手下的人員以及自己負(fù)責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...
摘要:因為管理人員是了解手下的人員以及自己負(fù)責(zé)的事情的。處理器優(yōu)化和指令重排上面提到在在和主存之間增加緩存,在多線程場景下會存在緩存一致性問題。有沒有發(fā)現(xiàn),緩存一致性問題其實就是可見性問題。 網(wǎng)上有很多關(guān)于Java內(nèi)存模型的文章,在《深入理解Java虛擬機(jī)》和《Java并發(fā)編程的藝術(shù)》等書中也都有關(guān)于這個知識點的介紹。但是,很多人讀完之后還是搞不清楚,甚至有的人說自己更懵了。本文,就來整體的...
摘要:內(nèi)存模型是圍繞著在并發(fā)過程中如何處理原子性可見性和有序性這個特征來建立的,我們來看下哪些操作實現(xiàn)了這個特性。可見性可見性是指當(dāng)一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。 Java內(nèi)存模型是圍繞著在并發(fā)過程中如何處理原子性、可見性和有序性這3個特征來建立的,我們來看下哪些操作實現(xiàn)了這3個特性。 原子性(atomicity): 由Java內(nèi)存模型來直接保證原子性變量操作包括...
閱讀 2475·2021-11-16 11:52
閱讀 2399·2021-11-11 16:55
閱讀 833·2021-09-02 15:41
閱讀 3056·2019-08-30 15:54
閱讀 3218·2019-08-30 15:54
閱讀 2322·2019-08-29 15:39
閱讀 1630·2019-08-29 15:18
閱讀 1052·2019-08-29 13:00