Java 關鍵字 volatile

volatile 是 Java 中的一個關鍵字,用于修飾變量,確保多線程環境下的可見性和有序性。它主要用于解決以下兩個問題:

  1. 可見性問題:一個線程對 volatile 變量的修改對其他線程立即可見。
  2. 有序性問題:禁止指令重排序,確保代碼的執行順序符合預期。

1. 可見性問題

在多線程環境中,每個線程都有自己的工作內存(緩存),線程對變量的操作通常是在工作內存中進行的。如果沒有同步機制,一個線程對變量的修改可能不會立即反映到主內存中,其他線程也就無法看到最新的值。

示例:非 volatile 變量的可見性問題
public class VisibilityProblem {private static boolean flag = false; // 非 volatile 變量public static void main(String[] args) {new Thread(() -> {while (!flag) {// 空循環}System.out.println("Flag is now true");}).start();try {Thread.sleep(1000); // 主線程休眠 1 秒} catch (InterruptedException e) {e.printStackTrace();}flag = true; // 修改 flag 的值System.out.println("Flag set to true");}
}

問題

  • 由于 flag 不是 volatile 變量,子線程可能無法看到主線程對 flag 的修改,導致子線程陷入死循環。
解決方案:使用 volatile
private static volatile boolean flag = false; // 使用 volatile 修飾

效果

  • volatile 確保對 flag 的修改立即寫入主內存,其他線程也能立即看到最新的值。

2. 有序性問題

Java 編譯器和處理器可能會對指令進行重排序以優化性能,但這可能導致多線程環境下的行為不符合預期。volatile 可以禁止指令重排序,確保代碼的執行順序符合程序員的意圖。

示例:指令重排序問題
public class ReorderingProblem {private static int x = 0;private static int y = 0;private static boolean ready = false;public static void main(String[] args) {new Thread(() -> {while (!ready) {// 空循環}System.out.println("x: " + x + ", y: " + y);}).start();x = 1;y = 2;ready = true;}
}

問題

  • 由于指令重排序,ready = true 可能會在 x = 1y = 2 之前執行,導致子線程看到 readytrue,但 xy 的值仍然是 0。
解決方案:使用 volatile
private static volatile boolean ready = false; // 使用 volatile 修飾

效果

  • volatile 禁止指令重排序,確保 ready = truex = 1y = 2 之后執行。

volatile 的工作原理

  1. 內存可見性
    • volatile 變量的寫操作會立即刷新到主內存。
    • volatile 變量的讀操作會從主內存中讀取最新的值。
  2. 禁止指令重排序
    • volatile 變量的讀寫操作前后會插入內存屏障(Memory Barrier),確保指令不會被重排序。

volatile 的局限性

  • 不保證原子性
    • volatile 只能保證單個讀/寫操作的原子性,但不能保證復合操作的原子性。
    • 例如,i++ 不是原子操作,即使 ivolatile 變量,多線程環境下仍然可能出現問題。
示例:volatile 不保證原子性
public class VolatileAtomicity {private static volatile int count = 0;public static void main(String[] args) throws InterruptedException {Runnable task = () -> {for (int i = 0; i < 1000; i++) {count++; // 非原子操作}};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();t1.join();t2.join();System.out.println("Final count: " + count); // 結果可能小于 2000}
}

解決方案

  • 使用 synchronizedjava.util.concurrent.atomic 包中的原子類(如 AtomicInteger)。

volatile 的使用場景

  1. 狀態標志

    • 例如,一個線程修改標志變量,另一個線程讀取標志變量。
    private volatile boolean running = true;public void stop() {running = false;
    }public void run() {while (running) {// 執行任務}
    }
    
  2. 雙重檢查鎖定(Double-Checked Locking)

    • 用于單例模式中,確保實例的可見性。
    public class Singleton {private static volatile Singleton instance;public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
    }
    

總結

  • volatile 用于解決多線程環境下的可見性和有序性問題。
  • 它不能保證復合操作的原子性,適用于簡單的狀態標志或雙重檢查鎖定等場景。
  • 如果需要更復雜的同步機制,可以結合 synchronized 或原子類使用。

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

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

相關文章

python網絡爬蟲開發實戰之基本庫使用

目錄 第二章 基本庫的使用 2.1 urllib的使用 1 發送請求 2 處理異常 3 解析鏈接 4 分析Robots協議 2.2 requests的使用 1 準備工作 2 實例引入 3 GET請求 4 POST請求 5 響應 6 高級用法 2.3 正則表達式 1 實例引入 2 match 3 search 4 findall 5 sub 6 com…

Linux內存分頁:原理、優勢與實踐

一、分頁機制核心原理 1.1 分頁技術原理 核心思想: 將虛擬地址空間和物理內存劃分為固定大小的頁(Page),通過頁表(Page Table)建立虛擬頁到物理頁框(Page Frame)的映射。例如,x86_64架構的4級頁表結構: 虛擬地址: [63-48] | [47-39] PGD | [38-30] PUD | [29-21]…

文件上傳漏洞與phpcms漏洞安全分析

目錄 1. 文件上傳漏洞簡介 2. 文件上傳漏洞的危害 3. 文件上傳漏洞的觸發條件 1. 文件必須能被服務器解析執行 2. 上傳目錄必須支持代碼執行 3. 需要能訪問上傳的文件 4. 例外情況&#xff1a;非腳本文件也可能被執行 4. 常見的攻擊手法 4.1 直接上傳惡意文件 4.2 文件…

模塊和端口

1、模塊 模塊內部的5個組成是&#xff1a;變量聲明 數據流語句 低層模塊實例 函數和任務 行為語句 SR鎖存器 timescale 1ns / 1psmodule SR_latch(input wire Sbar ,input wire Rbar ,output wire Q ,output wire Qbar);nand…

爬蟲(持續更新ing)

爬蟲&#xff08;持續更新ing&#xff09; # 網絡請求 # url統一資源定位符&#xff08;如&#xff1a;https://www.baidu.com&#xff09; # 請求過程&#xff1a;客戶端的web瀏覽器向服務器發起請求 # 請求又分為四部分&#xff1a;請求網址&#xff0c;請求方法&#xff08…

2025.3.2機器學習筆記:PINN文獻閱讀

2025.3.2周報 一、文獻閱讀題目信息摘要Abstract創新點網絡架構實驗結論不足以及展望 一、文獻閱讀 題目信息 題目&#xff1a; Physics-Informed Neural Networks of the Saint-Venant Equations for Downscaling a Large-Scale River Model期刊&#xff1a; Water Resource…

使用IDEA如何隱藏文件或文件夾

選擇file -> settings 選擇Editor -> File Types ->Ignored Files and Folders (忽略文件和目錄) 點擊號就可以指定想要隱藏的文件或文件夾

前端基礎之腳手架

腳手架結構 目錄結構 這里的package.json&#xff0c;存放著我們去執行npm run serve 或是npm run build的腳本文件 package-lock.json中存放著我們使用的外部包的版本類型&#xff0c;相當于maven src下的main.js是整個項目的入口文件 src下的components用于存放組件&#xff…

MacBook上API調??具推薦

在當今的軟件開發中&#xff0c;API調用工具已經成為了開發者不可或缺的助手。無論是前端、后端還是全棧開發&#xff0c;API的調試、測試和管理都是日常工作中的重要環節。想象一下&#xff0c;如果沒有這些工具&#xff0c;開發者可能需要手動編寫復雜的CURL命令&#xff0c;…

pgsql行列轉換

目錄 一、造測試數據 二、行轉列 1.函數定義 2.語法 3.示例 三、列轉行 1.函數定義 2.語法 3.示例 一、造測試數據 create table test ( id int, json1 varchar, json2 varchar );insert into test values(1,111,{111}); insert into test values(2,111,222,{111,22…

NVIDIA(英偉達) GPU 芯片架構發展史

GPU 性能的關鍵參數 CUDA 核心數量&#xff08;個&#xff09;&#xff1a;決定了 GPU 并行處理能力&#xff0c;在 AI 等并行計算類業務下&#xff0c;CUDA 核心越多性能越好。 顯存容量&#xff08;GB&#xff09;&#xff1a;決定了 GPU 加載數據量的大小&#xff0c;在 AI…

《Python實戰進階》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻擊

第10集&#xff1a;Web 安全性&#xff1a;防止 SQL 注入、XSS 和 CSRF 攻擊 在現代 Web 開發中&#xff0c;安全性是至關重要的。無論是用戶數據的保護&#xff0c;還是系統穩定性的維護&#xff0c;開發者都需要對常見的 Web 安全威脅有深刻的理解&#xff0c;并采取有效的防…

【大數據分析 | 深度學習】在Hadoop上實現分布式深度學習

【作者主頁】Francek Chen 【專欄介紹】 ? ? ?智能大數據分析 ? ? ? 智能大數據分析是指利用先進的技術和算法對大規模數據進行深入分析和挖掘&#xff0c;以提取有價值的信息和洞察。它結合了大數據技術、人工智能&#xff08;AI&#xff09;、機器學習&#xff08;ML&a…

盛鉑科技SCP4000射頻微波功率計與SPP5000系列脈沖峰值 USB功率計 區別

在射頻&#xff08;RF&#xff09;和微波測試領域&#xff0c;快速、精準的功率測量是確保通信系統、雷達、衛星設備等高性能運行的核心需求。無論是連續波&#xff08;CW&#xff09;信號的穩定性測試&#xff0c;還是脈沖信號的瞬態功率分析&#xff0c;工程師都需要輕量化、…

自學微信小程序的第十三天

DAY13 1、使用map組件在頁面中創建地圖后&#xff0c;若想在JS文件中對地圖進行控制&#xff0c;需要通過地圖API來完成。先通過wx.createMapContext()方法創建MapContext&#xff08;Map上下文&#xff09;實例&#xff0c;然后通過該實例的相關方法來操作map組件。 const m…

深入解析 C# 中的泛型:概念、用法與最佳實踐

C# 中的 泛型&#xff08;Generics&#xff09; 是一種強大的編程特性&#xff0c;允許開發者在不預先指定具體數據類型的情況下編寫代碼。通過泛型&#xff0c;C# 能夠讓我們編寫更靈活、可重用、類型安全且性能優良的代碼。泛型廣泛應用于類、方法、接口、委托、集合等多個方…

H5DS編輯器是如何讓企業快速構建動態頁面

H5DS編輯器核心亮點&#xff1a; 1.拖拽式操作&#xff0c;小白友好&#xff1a;無需設計與代碼基礎&#xff01;通過簡單拖拽元素、調整文字和動畫&#xff0c;即可生成交互式H5頁面。內置海量模板和素材庫&#xff0c;支持自定義設計風格&#xff0c;輕松適配企業品牌需求。…

Unity ECS與MonoBehaviour混合架構開發實踐指南

一、混合架構設計背景 1. 技術定位差異 ECS&#xff08;Entity Component System&#xff09;&#xff1a;面向數據設計&#xff08;DOD&#xff09;&#xff0c;適用于大規模實體計算&#xff08;如10萬單位戰斗&#xff09; MonoBehaviour&#xff1a;面向對象設計&#xf…

[項目]基于FreeRTOS的STM32四軸飛行器: 三.電源控制

基于FreeRTOS的STM32四軸飛行器: 三.電源控制 一.IP5305T芯片手冊二.電源控制任務 一.IP5305T芯片手冊 注意該芯片低功耗特性&#xff0c;為防止進入待機&#xff0c;每隔一段時間發送一個電平。 官方提供的芯片外圍電路設計圖&#xff1a; 電氣特性&#xff1a; 當負載電流持…

java環境部署

java環境部署 一、準備工作 jrejdkeclipse jdk下載&#xff1a;21和1.8-----官網&#xff1a;Oracle&#xff1a;Java 下載 |神諭 該處選擇要依據自身的系統類型選擇下載 idea的下載安裝&#xff1a;IntelliJ IDEA | Other Versions 二、安裝 三、環境配置 四、使用 五、i…