JVM happens-before 原則有哪些?

理解Java Memory Model (JMM) 中的 happens-before 原則對于編寫并發程序有很大幫助。

Happens-before 關系是 JMM 用來描述兩個操作之間的內存可見性以及執行順序的抽象概念。如果一個操作 A happens-before 另一個操作 B (記作 A hb B),那么 JMM 向你保證:

  1. A 的結果對 B 可見: 操作 A 的所有內存寫入操作,對于操作 B 來說都是可見的。也就是說,當執行操作 B 時,操作 A 之前對共享變量的修改值能夠被 B 讀取到。
  2. A 的執行順序先于 B: 在時間順序上,操作 A 在操作 B 之前發生。編譯器和處理器在重排序指令時,不會改變happens-before 關系的操作的順序(如果改變了會影響可見性或結果)。

需要注意的是,happens-before 并不是說操作 A 必須在操作 B 之前執行。它只是一種順序和可見性保證。如果兩個操作之間沒有 happens-before 關系,那么 JVM 可以對它們進行任意重排序,一個線程的修改對另一個線程也是不可見的。

JMM 定義了一系列的天然的 happens-before 原則,這些原則構成了所有并發操作的基礎:

  1. 程序順序規則 (Program Order Rule):

    • 在一個線程內,按照程序代碼的順序,書寫在前面的操作 happens-before 書寫在后面的操作。
    • 重要性: 這是最基本的保證,但僅限于單線程內。它不保證指令不會重排序(只要重排序不影響單線程內的結果),也不保證這些操作對其他線程的可見性。
  2. 管程鎖定規則 (Monitor Lock Rule):

    • 對一個管程(monitor,也就是 Java 中的內置鎖或 synchronized 關鍵字)的解鎖操作 happens-before 隨后對這個管程的加鎖操作。
    • 重要性: 這是 synchronized 實現可見性的基礎。當一個線程釋放鎖時,會將工作內存中的共享變量寫回主內存;當另一個線程獲取同一個鎖時,會清空工作內存,從主內存讀取共享變量的最新值。
  3. Volatile 變量規則 (Volatile Variable Rule):

    • 對一個 volatile 變量的寫入操作 happens-before 隨后對這個 volatile 變量的讀取操作。
    • 重要性: 確保了 volatile 變量的可見性。一個線程修改 volatile 變量后,這個修改會立即對其他線程可見。volatile 變量的讀寫還會形成內存屏障,禁止特定類型的指令重排序,保證了有序性。
  4. 線程啟動規則 (Thread Start Rule):

    • Thread.start() 的調用 happens-before 啟動的線程中的任何一個操作。
    • 重要性: 確保了新啟動的線程能夠看到主線程在調用 start() 之前對共享變量所做的修改。
  5. 線程終止規則 (Thread Termination Rule):

    • 線程中的所有操作 happens-before 其他線程檢測到這個線程已經終止。(例如,通過 Thread.join() 方法結束、或者 Thread.isAlive() 返回 false)。
    • 重要性: 確保了在被終止線程結束前對共享變量的修改,在調用 join() 的線程返回后能夠被看到。
  6. 線程中斷規則 (Thread Interruption Rule):

    • 對線程 interrupt() 方法的調用 happens-before 被中斷線程檢測到中斷事件的發生(例如,Thread.interrupted() 返回 true,或拋出 InterruptedException)。
    • 重要性: 保證了中斷操作的可見性。
  7. 對象終結規則 (Finalizer Rule):

    • 一個對象的初始化完成(構造函數執行結束)happens-before 它的 finalize() 方法的開始。
    • 重要性: 在對象被垃圾回收器回收并執行 finalize() 方法時,對象的字段已經初始化完畢。
  8. 傳遞性 (Transitivity):

    • 如果操作 A happens-before 操作 B,并且操作 B happens-before 操作 C,那么操作 A happens-before 操作 C。
    • 重要性: 這是 happens-before 關系能夠連接和傳遞的關鍵。通過這個規則,我們可以推導出更復雜的并發場景下的可見性保證。

happens-before 原則的意義:

  • 程序員的保證: JMM 承諾遵守這些 happens-before 規則,無論底層硬件和操作系統如何實現內存訪問。程序員可以依據這些規則來推理并發程序的正確性,而不必關心底層的復雜細節。
  • 同步機制的基礎: Java 中各種同步機制(如 synchronized, volatile, final, Lock, concurrent 包下的工具類)都是基于這些 happens-before 規則來實現對共享變量的正確訪問。例如,CountDownLatchcountDown() happens-before await() 方法成功返回。
  • 避免數據競爭: 如果兩個操作分別由不同的線程執行,它們訪問同一個共享變量,其中至少有一個是寫入操作,并且它們之間沒有 happens-before 關系,那么就存在數據競爭 (Data Race)。數據競爭會導致不可預測的結果。編寫并發程序就是要避免數據競爭,確保關鍵操作之間建立 happens-before 關系。

happens-before 原則不是描述實際的時間順序,而是定義了多線程環境下,哪些操作的結果必須對其他哪些操作可見,以及哪些操作的執行順序必須得到保證。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79833.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79833.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79833.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從 Eclipse Papyrus / XText 轉向.NET —— SCADE MBD技術的演化

從KPN[1]的萌芽開始,到SCADE的推出[2],再到Scade 6的技術更迭[3],SCADE 基于模型的開發技術已經歷許多。現在,Scade One 已開啟全新的探索 —— 從 Eclipse Papyrus / XText 轉向.NET 8跨平臺應用。 [1]: KPN, Kahn進程網絡 (197…

osquery在網絡安全入侵場景中的應用實戰(二)

背景 上次寫了osquery在網絡安全入侵場景中的應用實戰(一)結果還不錯,這次篇目二再增加一些場景。osquery主要解決的時員工被入侵之后電腦該如何溯源取證的問題。通常EDR會有日志,但是不會上報全量的日志。發現機器有惡意文件需要上級取證的時候,往往是比較麻煩的,會有這…

opencv+opencv_contrib+cuda和VS2022編譯

本文介紹使用OpenCV和OpenCV_Contrib源碼及Cuda進行編譯的過程,編譯過程中會用到OpenCV、OpenCV_Contrib、Toolkit、Cmake、VS2022等工具,最終編譯OpenCV的Cuda版本。 一、OpenCV下載地址 OpenCV官網下載地址:https://opencv.org/releases/#&#xff0…

spring中的@ConfigurationProperties注解詳解

一、核心功能與作用 ConfigurationProperties 是Spring Boot中用于將外部配置(如application.properties或application.yml中的屬性)綁定到Java對象的核心注解。其核心功能包括: 配置集中管理:將分散的配置屬性按前綴綁定到Java類…

【C/C++】函數模板

🎯 C 學習筆記:函數模板(Function Template) 本文是面向 C 初學者的函數模板學習筆記,內容包括基本概念、定義與使用、實例化過程、注意事項等,附帶示例代碼,便于理解與復現。 📌 一…

電子病歷高質量語料庫構建方法與架構項目(智能數據目錄篇)

電子病歷高質量語料庫的構建是醫療人工智能發展的基礎性工作,而智能數據目錄作為數據治理的核心組件,能夠有效管理這些語料資源。本文將系統闡述電子病歷高質量語料庫的構建方法與架構,特別聚焦于智能數據目錄的設計與實現,包括數據目錄的功能定位、元數據管理、構建步驟以…

前端懶加載(Lazy Loading)實戰指南

🚀 前端懶加載(Lazy Loading)實戰指南 懶加載是現代 Web 性能優化的“常規操作”。它的目標簡單直接:讓用戶只加載“當下真正需要的資源”。從靜態資源、組件、模塊到數據,每一層都可以使用懶加載技術,構建…

在 Ubuntu 系統中,查看已安裝程序的方法

在 Ubuntu 系統中,查看已安裝程序的方法取決于軟件的安裝方式(如通過 apt、snap、flatpak 或手動安裝)。以下是幾種常見方法: 通過 apt 包管理器安裝的軟件 適用于通過 apt 或 dpkg 安裝的 .deb 包。 列出所有已安裝的軟件包&…

性能優化實踐:性能監控體系

性能優化實踐:性能監控體系 在Flutter應用開發中,建立一個完善的性能監控體系對于保證應用質量和用戶體驗至關重要。本文將從實戰角度深入講解如何搭建Flutter應用的性能監控體系,包括監控指標的設計、數據采集實現、分析平臺搭建等內容。 …

kotlin 02flow-sharedFlow 完整教程

一 sharedFlow是什么 SharedFlow 是 Kotlin 協程中 Flow 的一種 熱流(Hot Flow),用于在多個訂閱者之間 共享事件或數據流。它適合處理 一次性事件(如導航、彈窗、Toast、刷新通知等),而不是持續狀態。 ? …

模擬開發授權平臺

這次只是實現應用的curd和公私鑰的校驗以及第三方的通知dmeo項目,大家可以拓開視野來編寫 進入主題 項目鏈接:桌角的眼鏡/develop_auth_platform 直接下拉并運行就行 回調應用代碼在test包中 回調應用測試代碼 package mainimport ("encoding/…

STM32 USART串口

一、通信接口 二、串口通信 串口是一種應用十分廣泛的通訊接口,串口成本低、容易使用、通信線路簡單,可實現兩個設備的互相通信單片機的串口可以使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信,極大地擴展了單片機的應用…

uniapp開發06-視頻組件video的使用注意事項

uniapp開發-視頻組件video的使用注意事項&#xff01;實際項目開發中&#xff0c;經常會遇到視頻播放的業務需求。下面簡單講解一下&#xff0c;uniapp官方提供的視頻播放組件video的常見參數和實際效果。 1&#xff1a;先看代碼&#xff1a; <!--視頻組件的使用展示-->…

【爬蟲】微博熱搜機

第一個下面一點&#xff1a; js代碼&#xff1a; const n require("crypto-js");let s n.SHA1(n.enc.Utf8.parse("tSdGtmwh49BcR1irt18mxG41dGsBuGKS")) , a n.enc.Hex.parse(s.toString(n.enc.Hex).substr(0, 32));function h(t) {let e (i t Stri…

軟考 系統架構設計師系列知識點之雜項集萃(51)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;50&#xff09; 第80題 設三個煤場A1、A2、A3分別能供應煤7、12、11萬噸&#xff0c;三個工廠B1、B2、B3分別需要10、10、10萬噸&#xff0c;從各煤場到各工廠運煤的單價&#xff08;百元/噸&…

npm,yarn,pnpm,cnpm,nvm,npx包管理器常用命令

前端比較主流的包管理器主要有三個npm&#xff0c;yarn&#xff0c;pnpm 多層級依賴&#xff0c;通常發生在依賴之間存在復雜的版本要求時 包 A 依賴于包 B1.0.0 包 B 依賴于包 C2.0.0 另一個包 D 也依賴于 C3.0.0 一、NPM (Node Package Manager) https://www.npmjs.cn/…

科普簡潔版:同態加密——密碼學的未來瑰寶

文章目錄 一、同態加密的基本概念1.1 什么是同態加密1.2 同態加密的數學本質1.3 同態加密的類型 二、主要同態加密方案詳解2.1 ElGamal加密2.2 Paillier加密2.3 Gentry的完全同態加密方案2.4 BGV方案2.5 BFV方案2.6 CKKS方案 三、同態加密的關鍵技術3.1 噪聲管理技術3.2 多項式…

力扣第448場周賽

賽時成績如下: 這應該是我力扣周賽的最好成績了(雖然還是三題) 1. 兩個數字的最大乘積 給定一個正整數 n。 返回 任意兩位數字 相乘所得的 最大 乘積。 注意&#xff1a;如果某個數字在 n 中出現多次&#xff0c;你可以多次使用該數字。 示例 1&#xff1a; 輸入&#xff1…

(一)Modular Monolith Architecture(項目結構/.net項目初始化/垂直切片架構)

文章目錄 項目地址一、項目結構1.1 Modules1. Events 模塊2. Users 模塊3. Ticketing 模塊4. Attendance 模塊1.2 數據庫模塊1.3 模塊架構選擇1. 全是Clean Architecture2. 分別使用不同的架構二、初始化項目2.1 本地創建項目結構1. 創建空的solution2. 添加基礎配置3. 創建git…

Java常用組件之Redis經典面試題(一)

大家好&#xff0c;今天為大家帶來Java項目中&#xff0c;幾乎必不可少的組件之一-Redis的一些常見面試題&#xff0c;幫忙近期需要面試的朋友們來一個理論基礎突擊&#xff01; 一、數據類型 1.Redis的常用數據類型有哪些 ? 難易程度&#xff1a;☆☆☆ 出現頻率&#xff1a;…