摘要:線程執(zhí)行與變量可見性的關(guān)系什么是的關(guān)系的關(guān)系是保證一個線程執(zhí)行的操作結(jié)果對不同線程中的另一個操作可見。執(zhí)行寫入和讀取到內(nèi)存的兩個線程可以在時鐘時間方面與其他操作保持一致,但可能看不到彼此一致的更改內(nèi)存一致性錯誤,除非它們有關(guān)系。
Java 線程執(zhí)行與變量可見性的 happen-before 關(guān)系 什么是 happen-before 的關(guān)系
happen-before 的關(guān)系是保證一個線程執(zhí)行的操作結(jié)果對不同線程中的另一個操作可見。
Happens-before 定義程序中所有操作的部分排序。為了保證執(zhí)行操作Y的線程可以看到操作X的結(jié)果(X和Y是否出現(xiàn)在不同的線程中),X和Y之間必然存在一個先發(fā)生的關(guān)系。在沒有happen-before 排序的情況下在兩個操作之間,JVM可以根據(jù)需要自由重新排序(JIT編譯器優(yōu)化)。
happen-before 的不僅僅是"時間"中的動作重新排序,而且還保證了對內(nèi)存的讀寫順序。執(zhí)行寫入和讀取到內(nèi)存的兩個線程可以在時鐘時間方面與其他操作保持一致,但可能看不到彼此一致的更改(內(nèi)存一致性錯誤),除非它們有happen-before 關(guān)系。
如何建立 happen-before 關(guān)系?以下是發(fā)生之前的規(guī)則:
單線程規(guī)則:單個線程中的每個操作都發(fā)生在該程序順序中稍后出現(xiàn)的該線程中的每個操作之前。
監(jiān)視器鎖定規(guī)則:監(jiān)視器鎖定(退出同步方法/塊)上的解鎖發(fā)生 - 在每次后續(xù)獲取同一監(jiān)視器鎖定之前。
易失性變量規(guī)則:在對該相同字段的每次后續(xù)讀取之前發(fā)生對易失性字段的寫入。易失性字段的寫入和讀取具有與進(jìn)入和退出監(jiān)視器(讀取和寫入時的同步塊)類似的內(nèi)存一致性效果,但實際上沒有獲取監(jiān)視器/鎖定。
線程啟動規(guī)則:線程上的 Thread.start() 調(diào)用發(fā)生在啟動線程中的每個操作之前。假設(shè)線程A通過調(diào)用threadA.start() 生成一個新線程B. 在線程B的run方法中執(zhí)行的所有操作都將看到線程A調(diào)用threadA.start() 方法,之前(僅在線程A中)發(fā)生在它們之前。
線程連接規(guī)則:線程中的所有操作都發(fā)生在任何其他線程從該線程上的連接成功返回之前。假設(shè)線程A通過調(diào)用threadA.start() 生成一個新線程B,然后調(diào)用threadA.join() 。線程A將在 join() 調(diào)用時等待,直到線程B的run方法完成。在join方法返回后,線程A中的所有后續(xù)操作都將看到線程B的run方法中執(zhí)行的所有操作都發(fā)生在它們之前。
傳遞性:如果A發(fā)生在B之前,B發(fā)生在C之前,那么A發(fā)生在C之前。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75687.html
摘要:順序一致性內(nèi)存模型有兩大特性一個線程中所有操作必須按照程序的順序執(zhí)行。這里的同步包括對常用同步原語的正確使用通過以下程序說明與順序一致性兩種內(nèi)存模型的對比順序一致性模型中所有操作完全按程序的順序串行執(zhí)行。 java內(nèi)存模型 java內(nèi)存模型基礎(chǔ) happen-before模型 JSR-133使用happen-before的概念來闡述操作之間的內(nèi)存可見性。在JMM中,如果一個操作執(zhí)行的結(jié)...
摘要:舉個例子,在多線程不使用環(huán)境中,每個線程會從主存中復(fù)制變量到緩存以提高性能。保證了變量的可見性關(guān)鍵字解決了變量的可見性問題。在多線程同時共享變量的情形下,關(guān)鍵字已不足以保證程序的并發(fā)性。 volatile 關(guān)鍵字能把 Java 變量標(biāo)記成被存儲到主存中。這表示每一次讀取 volatile 變量都會訪問計算機(jī)主存,而不是 CPU 緩存。每一次對 volatile 變量的寫操作不僅會寫到 ...
摘要:這個規(guī)則比較好理解,無論是在單線程環(huán)境還是多線程環(huán)境,一個鎖處于被鎖定狀態(tài),那么必須先執(zhí)行操作后面才能進(jìn)行操作。線程啟動規(guī)則獨享的方法先行于此線程的每一個動作。 1. 指令重排序 關(guān)于指令重排序的概念,比較復(fù)雜,不好理解。我們從一個例子分析: public class SimpleHappenBefore { /** 這是一個驗證結(jié)果的變量 */ private st...
摘要:異步非阻塞方式,任務(wù)的完成的通知由其他線程發(fā)出。并發(fā)并行死鎖饑餓活鎖死鎖線程持有,線程持有。如等,在多線程情況下,該操作不是原子級別的而是原子的,所以一般用于狀態(tài)標(biāo)記。 同步/異步、阻塞/非阻塞 同步/異步是 API 被調(diào)用者的通知方式。阻塞/非阻塞則是 API 調(diào)用者的等待方式(線程掛機(jī)/不掛起)。 同步非阻塞 Future方式,任務(wù)的完成要主線程自己判斷。如NIO,后臺有多個任務(wù)在...
摘要:當(dāng)線程執(zhí)行完后進(jìn)入狀態(tài),表示線程執(zhí)行結(jié)束。其中和表示兩個線程。但要注意,讓出并不表示當(dāng)前線程不執(zhí)行了。關(guān)鍵字其作用是防止指令重排和使線程對一個對象的修改令其他線程可見。 JMM特性一覽 Java Memory Model的關(guān)鍵技術(shù)點都是圍繞著多線程的原子性、可見性和有序性來建立的。因此我們首先需要來了解這些概念。 原子性(Atomicity) 原子性是指一個操作是不可中斷的。即使是在多...
閱讀 1927·2021-11-15 11:46
閱讀 1136·2021-10-26 09:49
閱讀 1867·2021-10-14 09:42
閱讀 3413·2021-09-26 09:55
閱讀 862·2019-08-30 13:58
閱讀 1061·2019-08-29 16:40
閱讀 3503·2019-08-26 10:27
閱讀 633·2019-08-23 18:18