真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JMM中happens-before的原理和使用方法

這篇文章主要介紹“JMM中happens-before的原理和使用方法”,在日常操作中,相信很多人在JMM中happens-before的原理和使用方法問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”JMM中happens-before的原理和使用方法”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

專注于為中小企業(yè)提供成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)臺(tái)江免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

在JMM中有一個(gè)很重要的概念對(duì)于我們了解JMM有很大的幫助,那就是happens-before規(guī)則。happens-before規(guī)則非常重要,它是判斷數(shù)據(jù)是否存在競(jìng)爭(zhēng)、線程是否安全的主要依據(jù)。JSR-133S使用happens-before概念闡述了兩個(gè)操作之間的內(nèi)存可見性。在JMM中,如果一個(gè)操作的結(jié)果需要對(duì)另一個(gè)操作可見,那么這兩個(gè)操作則存在happens-before關(guān)系。

那什么是happens-before呢?在JSR-133中,happens-before關(guān)系定義如下:

  1. 如果一個(gè)操作happens-before另一個(gè)操作,那么意味著第一個(gè)操作的結(jié)果對(duì)第二個(gè)操作可見,而且第一個(gè)操作的執(zhí)行順序?qū)⑴旁诘诙€(gè)操作的前面。

  2. 兩個(gè)操作之間存在happens-before關(guān)系,并不意味著Java平臺(tái)的具體實(shí)現(xiàn)必須按照happens-before關(guān)系指定的順序來執(zhí)行。如果重排序之后的結(jié)果,與按照happens-before關(guān)系來執(zhí)行的結(jié)果一致,那么這種重排序并不非法(也就是說,JMM允許這種重排序)

happens-before規(guī)則如下:

  1. 程序順序規(guī)則:一個(gè)線程中的每一個(gè)操作,happens-before于該線程中的任意后續(xù)操作。

  2. 監(jiān)視器規(guī)則:對(duì)一個(gè)鎖的解鎖,happens-before于隨后對(duì)這個(gè)鎖的加鎖。

  3. volatile規(guī)則:對(duì)一個(gè)volatile變量的寫,happens-before于任意后續(xù)對(duì)一個(gè)volatile變量的讀。

  4. 傳遞性:若果A happens-before B,B happens-before C,那么A happens-before C。

  5. 線程啟動(dòng)規(guī)則:Thread對(duì)象的start()方法,happens-before于這個(gè)線程的任意后續(xù)操作。

  6. 線程終止規(guī)則:線程中的任意操作,happens-before于該線程的終止監(jiān)測(cè)。我們可以通過Thread.join()方法結(jié)束、Thread.isAlive()的返回值等手段檢測(cè)到線程已經(jīng)終止執(zhí)行。

  7. 線程中斷操作:對(duì)線程interrupt()方法的調(diào)用,happens-before于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生,可以通過Thread.interrupted()方法檢測(cè)到線程是否有中斷發(fā)生。

  8. 對(duì)象終結(jié)規(guī)則:一個(gè)對(duì)象的初始化完成,happens-before于這個(gè)對(duì)象的finalize()方法的開始。

以上8條happens-before規(guī)則都比較簡(jiǎn)單,這里L(fēng)Z只分析第3條volatile變量規(guī)則,分析如下:

JMM中happens-before的原理和使用方法

從上圖中,我們看到存在4條happens-before關(guān)系,它們分別如下:

  • 1 happens-before 2 和 3 happens-before 4 是有由程序順序性規(guī)則產(chǎn)生的。

  • 2 happens-before 3 是由volatile規(guī)則產(chǎn)生的。上面提到過,一個(gè)volatile變量的讀,總能看到之前對(duì)這個(gè)volatile變量的寫入。

  • 1 happens-before 4 是由傳遞性規(guī)則產(chǎn)生的。

讀到這里,可能很多童鞋會(huì)把happens-before理解為“時(shí)間上的先后順序”,在這里L(fēng)Z特別強(qiáng)調(diào)happens-hefore不能理解為“時(shí)間上的先后順序”,下面LZ用一段代碼解釋寫happens-before和“時(shí)間上的先后順序”的不同,代碼如下:

public class VolatileTest4 {
    private int a = 0;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
}

上面代碼就是一組簡(jiǎn)單的setter/getter方法,現(xiàn)在假設(shè)現(xiàn)在有兩個(gè)線程A和B,線程A先(這里指時(shí)間上的先執(zhí)行)執(zhí)行setA(10),然后線程B訪問同一個(gè)對(duì)象的getA()方法,那么此時(shí)線程B收到的返回值是對(duì)少呢?

答案是:不確定

我們來一次分析下happens-before的各項(xiàng)原則:

  1. 這里兩個(gè)方法分別是在兩個(gè)線程中被調(diào)用,不在一個(gè)線程中,這里程序順序性就不適用了

  2. 代碼中沒有同步快,所有監(jiān)視器規(guī)則也不適用

  3. 代碼中變量a是一個(gè)普通變量,所以volatile規(guī)則也不適用

  4. 后面的線程啟動(dòng)、中斷、終止和對(duì)象的終結(jié)和這里完全沒有關(guān)系,因此這些規(guī)則也是不適用的

  5. 沒有一條happens-before適用,因此傳遞性規(guī)則也不適用

在這里,雖然線程A在時(shí)間上先于線程B執(zhí)行,但是由于代碼完全不適用happens-before規(guī)則,因此我們無法確定先B收到的值時(shí)多少。也就是說上面代碼是線程不安全的。

對(duì)于上面代碼,那我們?nèi)绾涡迯?fù)線程不安全這個(gè)問題呢?這里,我們只要滿足happens-before規(guī)則中2、3的任意一種規(guī)則就可以了。即要么把setter/getter方法定義為synchronized方法,要么在變量a上加volatile修飾符。

通過上面的例子,我們可以得出結(jié)論:一個(gè)操作“時(shí)間上的先發(fā)生”不代表這個(gè)操作會(huì)happens-before其它操作。那一個(gè)操作happens-before其它操作,是否就表示這個(gè)操作是“時(shí)間上先發(fā)生”的呢?答案也是否定的,我們來看看下面一個(gè)示例:

int i = 1;
int m = 2;

上面兩個(gè)賦值操作在同一個(gè)線程中,根據(jù)程序順序性規(guī)則,“int i = 1;"這個(gè)操作happens-before ”int m = 2;“這個(gè)操作,但是”int m = 2;“這個(gè)操作完全有可能被處理器先執(zhí)行,這并不影響happens-before原則的正確性。因?yàn)檫@種重排序在JMM中是允許的。

最后我們得出的結(jié)論是:時(shí)間先后順序與happens-before原則之間基本沒有太大的關(guān)系,所以我們?cè)诤饬坎l(fā)安全問題的時(shí)候不要受到時(shí)間順序的干擾,一切必須以happens-before原則為準(zhǔn)。 

到此,關(guān)于“JMM中happens-before的原理和使用方法”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


文章題目:JMM中happens-before的原理和使用方法
本文網(wǎng)址:http://weahome.cn/article/pgoeoe.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部