這篇文章主要介紹了java volatile關鍵字使用方法及注意事項的相關資料,當一個變量被聲明為volatile 後,java 內存模型確保所有使用該變量的線程能看到相同的、一致的值。 ,需要的朋友可以參考下
java volatile關鍵字使用方法及注意事項
什麼是volatile關鍵字
#volatile 關鍵字在多執行緒程式中扮演著很重要的角色。當多個執行緒操作同一個變數時,每個執行緒將擁有對那個變數的本地快取拷貝,因此,當某一個執行緒修改了這個變數的值時,實際上修改的是它本地快取中的變數值,而不是主記憶體中的變數值,操作這個變數的其他執行緒並不知道這個變數的值被改變了。為了避免這種情況,我們可以用valatile 關鍵字聲明這個變量,用valatile 聲明了這個變量之後,變量將不在本地緩存中保存,而在主內存中保存,當有線程修改了它的值以後,它的更新值將會更新到主記憶體當中,隨後,其他執行緒也能存取更新後的值。當一個變數被宣告為 volatile 後,java 記憶體模型確保所有使用該變數的執行緒都能看到相同的、一致的值。
volatile關鍵字使用首先,建立VolatileData 類,程式碼如下:
public class VolatileData { //声明为volatile类型 private volatile int counter = 0; /** * 返回counter变量的值 * @return */ public int getCounter() { return counter; } /** * 自增counter变量的值 */ public void increaseCounter() { ++counter; } }
接下來創建VolatileThread 類,程式碼如下:
public class VolatileThread extends Thread { private final VolatileData volatileData; public VolatileThread(VolatileData volatileData) { this.volatileData = volatileData; } /** * 调用VolatileData类中的两个方法,进行取值和自增操作 */ @Override public void run() { int oldValue = volatileData.getCounter(); System.out.println("[Thread " + Thread.currentThread().getId() + "]: Old value = " + oldValue); volatileData.increaseCounter(); int newValue = volatileData.getCounter(); System.out.println("[Thread " + Thread.currentThread().getId() + "]: New value = " + newValue); } }
最後,建立VolatileMain 類,對上述程式進行測試,程式碼如下:
public class VolatileMain { private final static int TOTAL_THREADS = 2; public static void main(String[] args) throws InterruptedException { VolatileData volatileData = new VolatileData(); Thread[] threads = new Thread[TOTAL_THREADS]; for(int i = 0; i < TOTAL_THREADS; ++i) threads[i] = new VolatileThread(volatileData); //开始读取变量值的操作 for(int i = 0; i < TOTAL_THREADS; ++i) threads[i].start(); //等待所有线程操作终止 for(int i = 0; i < TOTAL_THREADS; ++i) threads[i].join(); } }
在VolatileMain 類別中,使用了兩個執行緒來存取volatile 變量,輸出如下:
[Thread 10]: Old value = 0 [Thread 11]: Old value = 0 [Thread 10]: New value = 1 [Thread 11]: New value = 2
從輸出可以看到,首先,兩個執行緒都輸出了相同的值,接著,在increaseCounter 方法被呼叫之後,兩個執行緒都存取和輸出了最新的volatile 變數的值。
happens-before 關係式在使用 volatile 關鍵字時,我必須提及 java 記憶體模型的 happens-before 關係。 happens-before 關係是 java 記憶體模型的重要面向。它建立在兩個不同的事件之間,使第一個事件對物件的所有改變都可以被第二個事件看到和反映。例如當一個執行緒對 volatile 變數進行寫入操作後,另一個執行緒隨後存取該變量,happens-before 關係就建立了。因此,所有對 volatile 變數的改變對其他執行緒來說都是可見的。
需要注意的以上是Java中關於volatile關鍵字的使用與注意事項的詳細內容。更多資訊請關注PHP中文網其他相關文章!