volatile關鍵字解析

2021-10-06 12:52:54 字數 1333 閱讀 5712

volatile:

1.保證可見性

2.禁止重排序

我們先來看看乙個問題,關於i=i+1的問題。

首先,他不是乙個原子性的操作,我們通常將不可拆分的操作稱為原子操作

而i=i+1需要先在主存中取得i的值,之後複製到快取記憶體之中,cpu再從快取記憶體中讀取並計算之後存入快取記憶體,最後把值再存入記憶體中。

那麼怎麼來解決這個問題呢?

有兩種方法

第一種是lock加鎖,但是一定會損失併發性,加鎖之後其他cpu無法訪問

第二種是保證可見性,即當前cpu對這個資料進行更改時,其他資料也可以看到修改。

這個是通過共享變數來判斷的,將這個資料設定為共享資料,如果這個資料發生改變,其他持有該資料的cpu都會得到通知,將自己持有的作廢之後重新在記憶體中獲取。

上面我們講了一下關於可見性的問題

那麼下面我們來聊一聊關於重排序的問題

比如:a=1

a++b=1

我們將第二條和第三條語句交換位置,並不會改變結果

但是有時,看上去互不影響的語句交換順序是會影響最終結果的

例如://執行緒1 

int a=1

int flag = true;

//執行緒二

if(flag)

public static void main(string args) ;

}.start();

}while(thread.activecount()>1) //保證前面的執行緒都執行完

thread.yield();

system.out.println(test.inc);

}}最終inc的結果一定小於10000

因為inc++並不是原子性操作

我們前面說過,需要先在主存中取得i的值,之後複製到快取記憶體之中,cpu再從快取記憶體中讀取並計算之後存入快取記憶體,最後把值再存入記憶體中。

所有比如現在inc=1

當執行緒1讀取了inc的值,輪到執行緒二執行,執行緒二對inc讀取並加1,因為執行緒1只是讀取,所以執行緒二對資料的更改執行緒一並不知道,執行緒二將2寫入記憶體,執行緒一又將讀取的資料自增,最後還是2

本來應該是3 ,結果就出現了偏差

所以要保證正確性,就必須保證操作是原子性的

否則使用synchronized或者lock

volatile還有乙個經典的使用案例

單例模式中的雙重鎖

public class singleton   

public static singleton getinstance()

} }

return instance;

} }

volatile關鍵字解析

計算機執行程式時,每條指令都是在cpu中執行的,執行指令過程中,涉及到的資料的讀寫操作,程式執行過程中臨時資料都儲存在主存 物理記憶體 中,由於cpu的執行速度很快,所以資料的讀取和向記憶體中的的寫入相比較cpu的執行速度要慢很多,因此任何時候對資料的操作通過記憶體互動都會降低指令的執行速度,所以c...

Volatile關鍵字解析

volatile是j a虛擬機器提供的輕量級的同步機制 乞丐版 的synchronized 保證可見性 不保證原子性 禁止指令重排 可見性指當多個執行緒訪問同乙個變數時,如果其中乙個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值 驗證可見性demo import j a.util.con...

volatile關鍵字解析(一)

引起執行緒併發問題,可以簡單的總結為以下三條 原子性問題 什麼是原子性?原子性,即乙個操作或者多個操作,要麼全部執行並且執行過程中不會被任何因素打斷,要麼全部都不執行。如常見的銀行轉賬 count 操作等,都必須具備原子性才能保證不出現意外。a向b轉賬100元,需要保證兩步 a賬戶減100,b賬戶加...