Happens-beofre 先行發(fā)生原則(JVM 規(guī)范)

      網(wǎng)友投稿 626 2025-04-01

      如果JMM中所有的有序性都只靠volatile和synchronized,那么有一些操作將會變得很繁瑣,但我們在編寫Java并發(fā)代碼時并沒有感到這一點(diǎn),這是因?yàn)镴ava語言中有一個先行發(fā)生(Happen-Before)原則

      這個原則非常重要,它是判斷數(shù)據(jù)是否存在競爭,線程是否安全的主要依賴。

      先行發(fā)生原則

      指的是JMM中定義的兩項(xiàng)操作之間的依序關(guān)系

      happens- before關(guān)系 主要用于強(qiáng)調(diào)兩個有沖突的動作之間的順序,以及定義數(shù)據(jù)爭用的發(fā)生時機(jī)

      如果說操作A先行發(fā)生于操作B,就是在說發(fā)生B前,A產(chǎn)生的影響能被B觀察到,“影響”包含了修改內(nèi)存中共享變量的值、發(fā)送了消息、調(diào)用了方法等。意味著什么呢?如下例:

      //線程A中執(zhí)行 i = 1; //線程B中執(zhí)行 j = i; //線程C中執(zhí)行 i = 2;

      1

      2

      3

      4

      5

      6

      7

      8

      下面是JMM下一些”天然的“先行發(fā)生關(guān)系,無須任何同步器協(xié)助就已經(jīng)存在,可以在編碼中直接使用

      Happens-beofre 先行發(fā)生原則(JVM 規(guī)范)

      如果兩個操作之間的關(guān)系不在此列,并且無法從下列規(guī)則推導(dǎo)出來的話,它們就沒有順序性保障,虛擬機(jī)可以對它們進(jìn)行隨意地重排序

      具體的虛擬機(jī)實(shí)現(xiàn),有必要確保以下

      八大原則

      程序次序規(guī)則(Pragram Order Rule)

      在一個線程內(nèi),按照代碼順序,書寫在前面的操作先行發(fā)生于書寫在后面的操作。準(zhǔn)確地說應(yīng)該是控制流順序而不是程序代碼順序,因?yàn)橐紤]分支、循環(huán)結(jié)構(gòu)。

      對象鎖(監(jiān)視器鎖)法則(Monitor Lock Rule )

      某個 管程(也叫做對象鎖,監(jiān)視器鎖) 上的unlock動作happens-before同一個管程上后續(xù)的lock動作 。這里必須強(qiáng)調(diào)的是同一個鎖,而”后面“是指時間上的先后。

      volatile變量規(guī)則(Volatile Variable Rule)

      對某個volatile字段的寫操作happens- before每個后續(xù)對該volatile字段的讀操作,這里的”后面“同樣指時間上的先后順序。

      線程啟動規(guī)則(Thread Start Rule)

      在某個線程對象 上調(diào)用start()方法happens- before該啟動了的線程中的任意動作

      線程終止規(guī)則(Thread Termination Rule)

      某線程中的所有操作都先行發(fā)生于對此線程的終止檢測,我們可以通過Thread.join()方法結(jié)束(任意其它線程成功從該線程對象上的join()中返回),Thread.isAlive()的返回值等作段檢測到線程已經(jīng)終止執(zhí)行。

      線程中斷規(guī)則(Thread Interruption Rule)

      對線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測到中斷事件的發(fā)生,可以通過Thread.interrupted()方法檢測是否有中斷發(fā)生

      對象終結(jié)規(guī)則(Finalizer Rule)

      一個對象初始化完成(構(gòu)造方法執(zhí)行完成)先行發(fā)生于它的finalize()方法的開始

      傳遞性(Transitivity)

      如果操作A先行發(fā)生于操作B,操作B先行發(fā)生于操作C,那就可以得出操作A先行發(fā)生于操作C的結(jié)論

      一個操作”時間上的先發(fā)生“不代表這個操作會是”先行發(fā)生“,那如果一個操作”先行發(fā)生“是否就能推導(dǎo)出這個操作必定是”時間上的先發(fā)生“呢?也是不成立的,一個典型的例子就是指令重排序

      所以時間上的先后順序與先行發(fā)生原則之間基本沒有什么關(guān)系,所以衡量并發(fā)安全問題一切必須以先行發(fā)生原則為準(zhǔn)。

      上面八條是原生Java滿足Happens-before關(guān)系的規(guī)則,但是我們可以對他們進(jìn)行推導(dǎo)出

      其他滿足happens-before的案例

      將一個元素放入一個線程安全的隊(duì)列的操作Happens-Before從隊(duì)列中取出這個元素的操作

      將一個元素放入一個線程安全容器的操作Happens-Before從容器中取出這個元素的操作

      在CountDownLatch上的倒數(shù)操作Happens-Before CountDownLatch#await()操作

      Semaphore:release許可的操作Happens-Before acquire許可 的操作

      CyclicBarrier:線程中調(diào)用 await() 之前的操作 happen-before 那些是屏障操作的一部份的操作,后者依次 happen-before 緊跟在從另一個線程中對應(yīng) await() 成功返回的操作。

      Future表示的任務(wù)的所有操作Happens-Before Future#get()操作

      向Executor提交一個Runnable或Callable的操作Happens-Before任務(wù)開始執(zhí)行操作

      Java JVM 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:員工管理系統(tǒng)的五大好處
      下一篇:excel表格內(nèi)打平方符號的教程(表格中怎么打平方符號)
      相關(guān)文章
      亚洲精品成人在线| 一本色道久久88亚洲精品综合| 亚洲国产欧美一区二区三区| 亚洲高清日韩精品第一区| 亚洲精品天天影视综合网| 亚洲AV无码一区二区三区DV| 中文字幕亚洲无线码| 国内精品99亚洲免费高清| 久久久久亚洲AV成人网人人网站 | 国产亚洲精品第一综合| 亚洲丶国产丶欧美一区二区三区| 亚洲一本到无码av中文字幕 | 在线综合亚洲欧洲综合网站 | 日韩亚洲一区二区三区| 国产精品亚洲片在线| 亚洲熟妇无码AV在线播放| 亚洲永久精品ww47| 亚洲精品无码专区久久久 | 亚洲熟妇无码AV在线播放| 亚洲国产精品一区二区成人片国内| 亚洲av最新在线网址| 亚洲第一福利网站| 亚洲综合久久1区2区3区| 亚洲性色成人av天堂| 久久久久精品国产亚洲AV无码| 国产精品亚洲精品青青青 | 亚洲熟妇丰满多毛XXXX| 亚洲爱情岛论坛永久| 亚洲永久永久永久永久永久精品| 亚洲小视频在线观看| 亚洲国产精品成人精品软件| 亚洲天堂2016| 成人婷婷网色偷偷亚洲男人的天堂| 国产亚洲综合视频| 色噜噜亚洲精品中文字幕| 亚洲av无码不卡一区二区三区| 久久综合亚洲色HEZYO社区| 亚洲五月综合缴情婷婷| 国产精品亚洲综合一区在线观看| 亚洲精品第一国产综合精品99| 亚洲亚洲人成综合网络|