jmm,`as - if - serial` 與 `happens - before` 原則

在Java并發編程中,as - if - serialhappens - before 原則是確保程序在多線程環境下正確執行的重要規則,下面為你詳細講解:

as - if - serial原則

  1. 定義as - if - serial 原則是指,不管編譯器和處理器如何優化,單線程程序的執行結果都不能被改變。編譯器、處理器會遵守這個原則對單線程程序的執行順序進行優化,保證最終執行結果和代碼按照順序執行的結果一致。
  2. 目的:它的主要目的是在不改變程序執行結果的前提下,盡可能地提高單線程程序的執行效率。因為在單線程環境下,程序員無需擔心多線程帶來的并發問題,編譯器和處理器可以通過重排序等優化手段,讓程序運行得更快。
  3. 示例
int a = 1;
int b = 2;
int c = a + b;

在這個簡單的單線程代碼片段中,編譯器和處理器可能會對指令進行重排序。例如,它們可能先執行 int b = 2;,再執行 int a = 1;,最后執行 int c = a + b;。但無論如何重排序,最終 c 的值都會是 3,不會影響程序的執行結果,這就是 as - if - serial 原則的體現。

happens - before原則

  1. 定義happens - before 原則是Java內存模型(JMM)中定義的一種偏序關系,用于描述兩個操作之間的內存可見性。如果操作A happens - before 操作B,那么操作A的執行結果對操作B是可見的,并且操作A的執行順序在操作B之前。這里的“可見”不僅包括數據的可見性,還包括對內存操作順序的保證。
  2. 具體規則
    • 程序順序規則:在一個線程內,按照代碼順序,書寫在前面的操作 happens - before 書寫在后面的操作。例如:
int a = 1; // 操作A
int b = a + 1; // 操作B

這里操作A happens - before 操作B,因為在同一個線程內,代碼順序決定了執行順序和可見性。
- 監視器鎖規則:對一個鎖的解鎖操作 happens - before 后續對這個鎖的加鎖操作。例如:

synchronized (this) {// 臨界區1,鎖的加鎖操作int a = 1;
} // 鎖的解鎖操作synchronized (this) {// 鎖的加鎖操作int b = a + 1; // 這里能看到臨界區1中a的賦值結果
}

第一個 synchronized 塊的解鎖操作 happens - before 第二個 synchronized 塊的加鎖操作,所以第二個 synchronized 塊能看到第一個 synchronized 塊中對 a 的賦值。
- volatile變量規則:對一個 volatile 變量的寫操作 happens - before 后續對這個 volatile 變量的讀操作。例如:

volatile int a;Thread thread1 = new Thread(() -> {a = 1; // 對volatile變量a的寫操作
});Thread thread2 = new Thread(() -> {int b = a; // 對volatile變量a的讀操作,能看到thread1中對a的賦值
});

由于 avolatile 變量,所以 thread1 中對 a 的寫操作 happens - before thread2 中對 a 的讀操作。
- 線程啟動規則Thread 對象的 start() 方法 happens - before 此線程的每一個動作。例如:

Thread thread = new Thread(() -> {int a = 1;
});
thread.start(); // start()方法happens - before線程內部的操作

start() 方法的調用 happens - before 線程內部對 a 的賦值操作,保證線程啟動后能正確執行內部代碼。
- 線程終止規則:線程中的所有操作都 happens - before 對此線程的終止檢測。例如:

Thread thread = new Thread(() -> {int a = 1;
});
thread.start();
thread.join(); // 等待線程終止,線程內部所有操作happens - before這里

thread.join() 能保證在其之前線程內部的所有操作都已完成。
- 線程中斷規則:對線程 interrupt() 方法的調用 happens - before 被中斷線程的代碼檢測到中斷事件的發生。例如:

Thread thread = new Thread(() -> {while (!Thread.currentThread().isInterrupted()) {// 循環}
});
thread.start();
thread.interrupt(); // interrupt()方法調用happens - before線程內部對中斷的檢測

interrupt() 方法的調用 happens - before 線程內部對中斷狀態的檢測。
- 對象終結規則:一個對象的初始化完成(構造函數執行結束) happens - before 它的 finalize() 方法的開始。
3. 作用happens - before 原則為多線程編程提供了一種內存可見性的保障機制。通過這些規則,程序員可以判斷在多線程環境下,一個操作的結果是否對另一個操作可見,從而避免數據競爭和其他并發問題。同時,它也為編譯器和處理器的優化提供了一定的限制,即優化不能違反 happens - before 原則,以確保多線程程序的正確性。

as - if - serial 原則主要針對單線程程序的優化,而 happens - before 原則則重點解決多線程環境下的內存可見性和操作順序問題,兩者共同保證了Java程序在不同執行環境下的正確性和高效性。

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

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

相關文章

主流大模型Agent框架 AutoGPT詳解

注:此文章內容均節選自充電了么創始人,CEO兼CTO陳敬雷老師的新書《GPT多模態大模型與AI Agent智能體》(跟我一起學人工智能)【陳敬雷編著】【清華大學出版社】 GPT多模態大模型與AI Agent智能體書籍本章配套視頻課程【陳敬雷】 文…

kotlin學習,val使用get()的問題

疑問:定義val怎么還能使用get()代碼示例:private val nametype:Intget()Business.carInfo?.let{carSc(it)}?:LType.AS回答:Kotlin 允許為屬性定義自定義 getter,每次訪問屬性時會執行該方法疑問:這里引出另一個不解&…

解決el-select數據類型相同但是顯示數字的問題

這個不是我寫的&#xff0c;只是遇到的bug&#xff0c;寫法問題&#xff0c;忽略了值的綁定的問題源代碼bug&#xff1a;<el-selectv-model"schemeInfo.horizon"placeholder"請選擇起報月份"clearablefilterable><el-option v-for"(option,i…

熟練掌握RabbitMQ和Kafka的使用及相關應用場景。異步通知與解耦,流量削峰,配合本地消息表實現事務的最終一致性并解決消息可靠、順序消費和錯誤重試等問題

RabbitMQstock.#.nyse &#xff0c;#匹配多個字符&#xff0c;*匹配一個字符。 Confirm Callback 到達exchange的回調。 Return Callback 到達queue失敗的回調。 Kafka Kafka生產端分區器&#xff1a; 1.直接指定partition 指定0,1。 2.設置hashkey&#xff0c;計算key的hash值…

飛算科技:以原創技術賦能數字轉型

在數字科技迅猛發展的浪潮中&#xff0c;飛算數智科技&#xff08;深圳&#xff09;有限公司&#xff08;簡稱 “飛算科技”&#xff09;作為一家自主創新型的數字科技公司&#xff0c;同時也是國家級高新技術企業&#xff0c;正以扎實的技術實力和豐富的實踐經驗&#xff0c;在…

基于 Rust 的Actix Web 框架的應用與優化實例

基于 Rust 的Actix Web 框架的應用與優化實例 Actix Web 框架概述 Actix Web 是一個基于 Rust 的高性能、輕量級 Web 框架,構建于 Actix 異步運行時之上。它支持異步編程模型,適合構建高并發、低延遲的 Web 服務和 API。 核心特性 異步支持:基于 async/await 語法,充分利…

springMVC01-特點、創建項目、@RequestMapping、獲取參數請求,三種域對象

一、簡介 SpringMVC 就是 Spring 框架中的 MVC 模塊&#xff0c;用于構建 Web 應用中的“控制層”。 SpringMVC 是 Spring 提供的一個基于 Servlet 的 Web MVC 框架模塊&#xff0c;是 Spring 整個體系中的“Web 層核心”。 SpringMVC 是 Spring 的一部分&#xff0c;Spring…

Java基礎,反射破壞封裝性 - 單例模式的崩塌

目錄一、容易出現問題的小李代碼小李的單例設計看似完美&#xff0c;實則存在三個致命問題&#xff1a;1、反射攻擊的天然漏洞2、序列化的隱患3、性能瓶頸二、隔壁老王的優化方案三、為什么這樣優化&#xff1f;四、小結周五下午&#xff0c;代碼審查會議上&#xff0c;小李自信…

Neo4j 綜合練習作業

Neo4j 綜合練習作業 作業說明 這個作業涵蓋了 Neo4j 的多個重要知識點&#xff0c;包括節點和關系的創建、查詢、更新、刪除以及高級查詢功能。請使用 Cypher 語句完成以下所有題目。 數據準備 首先執行以下語句創建示例數據&#xff1a; ACTED_IN: 表示出演關系 DIRECTED: 表示…

基于PA算法的FTL引導

一、抽象綁定關系 1. 什么是 AF Block,什么是 NF Block,為什么要將多個 NF Block 綁定為一個 AF Block AF Block(Allocation Flash Block) 和 NF Block(NAND Flash Block) 是在 NAND Flash 存儲架構中用于管理數據的基本單位。 AF Block 定義:AF Block 是一組多個 NF…

快速入門Java中的IO操作

以下是 Java 中常用的 IO 知識點總結&#xff1a; 1. 流的分類 按數據流向&#xff1a;輸入流&#xff08;讀取數據&#xff09;和輸出流&#xff08;寫入數據&#xff09;。按數據類型&#xff1a;字節流&#xff08;處理二進制數據&#xff0c;以字節為單位&#xff09;和字符…

小程序軟裝: 組件庫開發

本節概述 經過前面小節的學習&#xff0c;我們已經搭建起了小程序的編譯構建環境&#xff0c;能夠將我們開發的小程序項目編譯成為對應的邏輯代碼文件 logic.js&#xff0c;頁面渲染文件 view.js&#xff0c;樣式文件 style.css 和配置文件 config.json 在編譯小程序的過程中…

250708-Debian系統安裝Edge瀏覽器并配置最小中文輸入法

在 Debian 系統上安裝 Microsoft Edge 瀏覽器可以通過以下幾種方式進行。Microsoft 官方提供了 .deb 安裝包&#xff0c;適用于 Debian、Ubuntu 及其衍生系統。 A. 如何安裝&#xff1f; ? 方法一&#xff1a;使用 .deb 安裝包&#xff08;推薦&#xff09; 步驟 1&#xff…

docker所占硬盤內存指令

使用下面命令可以查看docker所占的硬盤大小&#xff0c;如&#xff1a;docker system dfdocker system df -v

A1126LLHLX-T Allegro霍爾效應鎖存器,5kHz+推挽輸出,汽車級轉速檢測專家!

A1126LLHLX-T&#xff08;Allegro&#xff09;產品解析一、產品定位A1126LLHLX-T是Allegro MicroSystems推出的全極性霍爾效應鎖存器&#xff0c;采用超薄SOT-23W封裝&#xff08;1mm厚度&#xff09;&#xff0c;專為高可靠性位置檢測與轉速測量設計&#xff0c;具有低功耗、高…

【C#】File從后往前讀取文件指定行數

/// <summary>/// 從后往前讀取文件最后行數據/// </summary>/// <param name"filePath"></param>/// <param name"count"></param>/// <returns></returns>public static List<string> ReadFileRe…

暑假算法日記第五天

目標?&#xff1a;刷完靈神專題訓練算法題單 階段目標&#x1f4cc;&#xff1a;【算法題單】滑動窗口與雙指針 LeetCode題目:683. K 個關閉的燈泡2067. 等計數子串的數量2524. 子數組的最大頻率分數2269. 找到一個數字的 K 美麗值1984. 學生分數的最小差值1461. 檢查一個字符…

【05】MFC入門到精通——MFC 為對話框中的控件添加變量 和 數據交換和檢驗

文章目錄四、 為對話框中的控件添加變量五、對話框類的5.1 為編輯框添加變量面步驟中 為對話框添加了幾個控件&#xff0c;包括三個靜態文本框&#xff0c;三個編輯框&#xff0c;一個按鈕控件。 四、 為對話框中的控件添加變量 編輯框中的數據可能會經常變化&#xff0c;有必…

4-Kafka-partition(分區)概念

Kafka Topic 分區詳解 &#x1f4cc; 一、分區核心概念 1. 什么是分區&#xff1f; 物理分片&#xff1a;Topic 被劃分為多個分區&#xff08;Partition&#xff09;&#xff0c;每個分區是一個有序、不可變的消息序列存儲單位&#xff1a;每個分區對應一個物理日志文件&…

論文略讀:UniPELT: A Unified Framework for Parameter-Efficient Language Model Tuning

ACL 2021 LoRAPrefix TuningAdapter門控藍色參數是可訓練的參數