Java多執行緒程式設計那些事:volatile解惑
1、 前言
\\volatile關鍵字可能是Java開發人員“熟悉而又陌生”的一個關鍵字。本文將從volatile關鍵字的作用、開銷和典型應用場景以及Java虛擬機器對volatile關鍵字的實現這幾個方面為讀者全面深入剖析volatile關鍵字。
\\volatile字面上有“揮發性的,不穩定的”意思,它是用於修飾可變共享變數(Mutable Shared Variable)的一個關鍵字。所謂“共享”是指一個變數能夠被多個執行緒訪問(包括讀/寫),所謂“可變”是指變數的值可以發生變化。換而言之,volatile關鍵字用於修飾多個執行緒併發訪問的同一個變數,這些執行緒中至少有一個執行緒會更新這個變數的值。我們稱volatile修飾的變數為volatile變數。我們知道鎖的作用包括保障原子性、保障可見性以及保障有序性。volatile常被稱為“輕量級鎖”,其作用與鎖有類似的地方——volatile也能夠保障原子性(僅保障long/double型變數訪問操作的原子性)、保障可見性以及保障有序性。
\\本文所提及的“Java虛擬機器”如無特別說明,均特指Oracle公司的HotSpot Java虛擬機器。
\\2. 保障long/double型變數訪問操作的原子性
\\不可分割的操作被稱為原子操作(Atomic Operation)。所謂不可分割(Indivisible)是指一個操作從其執行執行緒以外的其他執行緒看來,該操作要麼已經完成要麼尚未開始,也就是說其他執行緒不會看到該操作的中間結果。如果一個操作是原子操作,那麼我們就稱該操作具有原子性(Atomicity)。
\\Java語言規範(Java Language Specification,JLS)規定,Java語言中針對long/double型以外的任何變數(包括基礎型別變數和引用型變數)進行的讀、寫操作都是原子操作,即Java語言規範本身並不規定針對long/double型變數進行讀、寫操作具有原子性。一個long/double型變數的讀/寫操作在32位Java虛擬機器下可能會被分解為兩個子步驟(比如先寫低32位,再寫高32位)來實現,這就導致一個執行緒對long/double型變數進行的寫操作的中間結果可以被其他執行緒所觀察到,即此時針對long/double型變數的訪問操作不是原子操作。清單1所示的實驗展示了這點。
\\清單1 long/double型變數寫操作的原子性問題Demo
\\\/**\\* 本Demo必須使用32位Java虛擬機器才能看到非原子操作的效果. \u0026lt;br\u0026gt;\\* 執行本Demo時也可以指定虛擬機器引數“-client”\\*\\* @author Viscent Huang\\*/\\public class NonAtomicAssignmentDemo implements Runnable {\\static long value = 0;\\private final long valueToSet;\\public NonAtomicAssignmentDemo(long valueToSet) {\\this.valueToSet = valueToSet;\\}\\public static void main(String[] args) {\\// 執行緒updateThread1將data更新為0\\Thread updateThread1 = new Thread(new NonAtomicAssignmentDemo(0L));\\// 執行緒updateThread2將data更新為-1\\Thread updateThread2 = new Thread(new NonAtomicAssignmentDemo(-1L));\\updateThread1.start();\\updateThread2.start();\\// 不進行實際輸出的OutputStream\\final DummyOutputStream dos = new DummyOutputStream();\\try (PrintStream dummyPrintSteam = new PrintStream(dos);) {\\// 共享變數value的快照(即瞬間值)\\long snapshot;\\while (0 == (snapshot = value) || -1 == snapshot) {\\// 不進行實際的輸出,僅僅是為了阻止JIT編譯器做迴圈不變表示式外提優化\\dummyPrintSteam.print(snapshot);\\}\\System.err.printf(\"Unexpected data: %d(0x%016x)\
相關文章
- Java多執行緒——volatileJava執行緒
- Java多執行緒(四):volatileJava執行緒
- Java多執行緒(六) volatileJava執行緒
- JAVA執行緒的那些事?Java執行緒
- 多核和多執行緒那些事執行緒
- 多執行緒併發程式設計“鎖”事執行緒程式設計
- java多執行緒之volatile理解Java執行緒
- Java多執行緒之初識volatileJava執行緒
- Java執行緒池的那些事Java執行緒
- 【QT】 Qt多執行緒的“那些事”QT執行緒
- iOS多執行緒的那些事兒iOS執行緒
- Java多執行緒程式設計基礎Java執行緒程式設計
- Java多執行緒程式設計要點Java執行緒程式設計
- 程式設計思想之多執行緒與多程式(3):Java 中的多執行緒程式設計執行緒Java
- 多執行緒程式設計執行緒程式設計
- Java基礎之執行緒那些事Java執行緒
- 細說C#多執行緒那些事:執行緒基礎C#執行緒
- Java多執行緒程式設計—鎖優化Java執行緒程式設計優化
- Java-基礎程式設計-多執行緒Java程式設計執行緒
- java多執行緒程式設計--基礎篇Java執行緒程式設計
- Java多執行緒程式設計要點 (一)Java執行緒程式設計
- Java 多執行緒程式設計要點(synchronized)Java執行緒程式設計synchronized
- Java多執行緒程式設計入門(轉)Java執行緒程式設計
- 使用Java實現多執行緒程式設計Java執行緒程式設計
- Java多執行緒(二)volatile關鍵字Java執行緒
- java多執行緒4:volatile關鍵字Java執行緒
- JavaScript多執行緒程式設計JavaScript執行緒程式設計
- Boost多執行緒程式設計執行緒程式設計
- UNIX多執行緒程式設計執行緒程式設計
- 多執行緒程式設計(轉)執行緒程式設計
- Java多執行緒事務管理Java執行緒
- java多執行緒程式設計chap5-7Java執行緒程式設計
- java多執行緒程式設計chap1-2Java執行緒程式設計
- java多執行緒程式設計chap3-4Java執行緒程式設計
- Java多執行緒程式設計之同步器Java執行緒程式設計
- Java多執行緒程式設計——進階篇一Java執行緒程式設計
- Java多執行緒程式設計——進階篇二Java執行緒程式設計
- 深入淺出Java多執行緒程式設計(轉)Java執行緒程式設計