JUC併發編程學習筆記(十五)JMM

来源:https://www.cnblogs.com/nhgtx/archive/2023/11/07/17806030.html
-Advertisement-
Play Games

JMM 請你談談對Volatile的理解 Volatile是java虛擬機提供的輕量級的同步機制 1、保證可見性 2、不保證原子性 3、禁止指令重排 什麼是JMM JVM->java虛擬機 JMM->java記憶體模型,不存在的東西,概念!約定 關於JMM的一些同步的約定: 線程解鎖前,必須把共用變數 ...


JMM

請你談談對Volatile的理解

Volatile是java虛擬機提供的輕量級的同步機制

1、保證可見性

2、不保證原子性

3、禁止指令重排

什麼是JMM

JVM->java虛擬機

JMM->java記憶體模型,不存在的東西,概念!約定

關於JMM的一些同步的約定:

  • 線程解鎖前,必須把共用變數立刻刷回主存

  • 線程加鎖前,必須讀取主存中的最小值到工作記憶體中!

  • 必須要保證加鎖和解鎖時同一把鎖

線程------->工作記憶體主記憶體

詳見:Java記憶體模型(JMM)詳解 - 程式新視界 - 博客園 (cnblogs.com)

在此交互過程中,Java記憶體模型定義了8種操作來完成,虛擬機實現必須保證每一種操作都是原子的、不可再拆分的(double和long類型例外)。

  • lock(鎖定):作用於主記憶體的變數,它把一個變數標識為一條線程獨占的狀態。
  • unlock(解鎖):作用於主記憶體的變數,它把一個處於鎖定狀態的變數釋放出來,釋放後的變數才可以被其他線程鎖定。
  • read(讀取):作用於主記憶體的變數,它把一個變數的值從主記憶體傳輸到線程的工作記憶體中,以便隨後的load動作使用。
  • load(載入):作用於工作記憶體的變數,它把read操作從主記憶體中得到的變數值放入工作記憶體的變數副本中。
  • use(使用):作用於工作記憶體的變數,它把工作記憶體中一個變數的值傳遞給執行引擎,每當虛擬機遇到一個需要使用到變數的值的位元組碼指令時將會執行這個操作。
  • assign(賦值):作用於工作記憶體的變數,它把一個從執行引擎接收到的值賦給工作記憶體的變數,每當虛擬機遇到一個給變數賦值的位元組碼指令時執行這個操作。
  • store(存儲):作用於工作記憶體的變數,它把工作記憶體中一個變數的值傳送到主記憶體中,以便隨後的write操作使用。
  • write(寫入):作用於主記憶體的變數,它把store操作從工作記憶體中得到的變數的值放入主記憶體的變數中。

Java記憶體模型還規定了在執行上述8中基本操作時必須滿足如下規則。

  • 不允許read和load、store和write操作之一單獨出現,即不允許一個變數從主記憶體讀取了但工作記憶體不接受,或者從工作記憶體發起回寫了但主記憶體不接受的情況出現。
  • 不允許一個線程丟棄它的最近的assign操作,即變數在工作記憶體中改變了之後必須把該變化同步回主記憶體。
  • 不允許一個線程無原因地(沒有發生過任何assign操作)把數據從線程的工作記憶體同步回主記憶體。
  • 一個新的變數只能在主記憶體中“誕生”,不允許在工作記憶體中直接使用一個未被初始化(load或assign)的變數,換句話說,就是對一個變數實施use、store操作之前,必須先執行過了assign和load操作。
  • 一個變數在同一時刻只允許一條線程對其進行lock操作,但lock操作可以被同一條線程重覆執行多次,多次執行lock後,只有執行相同次數的unlock操作,變數才會被解鎖。
  • 如果對一個變數執行lock操作,那將會清空工作記憶體中此變數的值,在執行引擎使用這個變數前,需要重新執行load或assign操作初始化變數的值。
  • 如果一個變數事先沒有被lock操作鎖定,那就不允許對它執行unlock操作,也不允許去unlock一個被其他線程鎖定住的變數。
  • 對一個變數執行unlock操作之前,必須先把此變數同步回主記憶體中(執行store、write操作)。

模擬主記憶體中數據被修改後未能獲取到最新數據的子線程的工作記憶體狀態

package org.example.tvolatile;

import java.util.concurrent.TimeUnit;

public class JMMDemo01 {
    //定義變數
    private static Integer num = 0;
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            //只要num=0就一直迴圈,來模擬主線程數據被改變後子線程的狀態
            while (num==0){

            }
            System.out.println("子線程執行結束,num已經不等於0了");
        }).start();
        //休眠疫苗等待子線程開啟
        TimeUnit.SECONDS.sleep(1);
        //修改值
        num=1;
        System.out.println(num);

    }
}

結果就是當主記憶體中的值已經被改變了,但是子線程中的工作記憶體不知道,所以還在一直迴圈

程式一直沒有結束!

問題:子線程中的工作記憶體不知道主記憶體的值已經被修改過了

------------------>引出Volatile,Volatile就能解決這個問題


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1 任務調度整體流程 2 組件 調度器 :工廠類創建Scheduler,根據觸發器定義的時間規則調度任務 任務:Job表示被調度的任務 觸發器:Trigger 定義調度時間的元素,按啥時間規則執行任務。一個Job可被多個Trigger關聯,但是一個Trigger 只能關聯一個Job import o ...
  • 進行支付寶開發的第一步就是:配置密鑰。 但是有很多小伙伴都不知道怎麼配置,這篇文章將手把手幫你從頭開始捋清如何配置支付寶密鑰~ ...
  • 在"zookeeper源碼(03)集群啟動流程"中介紹了leader選舉的入口,本文將詳細分析leader選舉組件和流程。 leader選舉流程(重要) quorumPeer的start階段使用startLeaderElection()方法啟動選舉 LOOKING狀態,投自己一票 createEle ...
  • 準備 我是小C同學編寫得一個java文件,如何實現我的功能呢?需要去JVM(Java Virtual Machine)這個地方旅行。 變身 我高高興興的來到JVM,想要開始JVM之旅,它確說:“現在的我還不能進去,需要做一次轉換,生成class文件才行”。為什麼這樣呢? JVM不能直接載入java文 ...
  • 配置文件yml # phantomjs的位置地址 phantomjs: binPath: windows: binPath-win linux: binPath-linux jsPath: windows: jsPath-win linux: jsPath-linux imagePath: wind ...
  • 定時任務簡介 定時任務是指按照預定的時間間隔或特定時間點自動執行的計劃任務或操作。這些任務通常用於自動化重覆性的工作,以減輕人工操作的負擔,提高效率。在電腦編程和應用程式開發中,定時任務是一種常見的編程模式,用於周期性地執行某些操作、處理數據或觸發事件。 以下是一些關於定時任務的重要概念: 時間間 ...
  • 插值運算是一種數據處理方法,主要用來填補數據之間的空白或缺失值。因為在實際應用中,數據往往不是完整的,而是存在著空白或缺失值,這些空白或缺失值可能是由於數據採集困難、數據丟失或數據處理錯誤等原因造成的。如果直接使用這些空白或缺失值進行分析和預測,將會對結果造成很大的影響。 插值運算可以用來填補這些空 ...
  • 是極致魅惑、灑脫自由的Java heap space?是知性柔情、溫婉大氣的GC overhead limit exceeded?是純真無邪、活潑可愛的Metaspace?如果以上不是你的菜,那還有……刁蠻任性,無跡可尋的CodeCache!性感火辣、心思細膩的Direct Memory高貴冷艷,獨... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...