volatile關鍵字解析(一)

2022-04-12 01:46:29 字數 1547 閱讀 4755

引起執行緒併發問題,可以簡單的總結為以下三條:

原子性問題

什麼是原子性?

原子性,即乙個操作或者多個操作,要麼全部執行並且執行過程中不會被任何因素打斷,要麼全部都不執行。

如常見的銀行轉賬、count++操作等,都必須具備原子性才能保證不出現意外。

a向b轉賬100元,需要保證兩步:a賬戶減100,b賬戶加100,如果有任何乙個發生意外,總有不滿意的一方,a賬戶減了100,b賬戶沒有加100,客戶肯定不滿意;a賬戶由於某種原因沒有減100,但是b賬戶卻加了100,銀行此時肯定也不幹(畢竟是國內,你懂得)。

可見性問題

什麼是可見性?

可見性是指當多個消除訪問同乙個變數時,乙個執行緒修改了這個變數的值,其他執行緒能夠立即看到修改的值。

同樣舉個例子來說明一下:

public

class runthread extends

thread

public

void setrunning(boolean

isrunning)

@override

public

void

run()

system.out.println("執行緒執行完成了");

}}public

class

testrun

catch

(exception e)

} }

我們會發現,runthread執行緒無法正常結束了,進入了死迴圈了。這是由於在主線程中修改的isrunning值,並沒有及時對runthread執行緒感知到,這就是可見性的問題,由於主線程修改了之後,runthread執行緒並沒有立即能看到。

有序性問題

什麼是有序性?

有序性即程式執行的順序按照**的先後順序執行。

int a = 0;

int b = 0;

a = 1; //

語句1b = 2; //

語句2int c = a * a;//

語句3

int d = b + c;//

語句4

從上述**看,語句1在語句2之前執行,但是對於jvm來說情況未必如此,這就是指令重排序。

volatile使用場景

當需要避免併發時發生意想不到的結果,必須要保證以上三條都滿足,否則極有可能得到你不想要的結果,我們常用的操作有synchronized和lock來保證這些情況,但是有些情況下,我們其實可以使用輕量級併發volatile關鍵字,

但是它並不能保證原子性操作,因此,volatile並不能替代synchronized。

關於volatile使用的場景:

常見的場景有:

什麼是指令重排序呢?簡單多說,就是處理器為了提公升程式的執行效率,可能對輸入的**進行優化,它不保證程式各個語句的執行先後順序同**中的順利一致,但保證最後的結果和順序執行是一直的。

由於語句4依賴於語句3,則兩者的順序是不會調整的。

volatile關鍵字解析

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

volatile關鍵字解析

volatile 1.保證可見性 2.禁止重排序 我們先來看看乙個問題,關於i i 1的問題。首先,他不是乙個原子性的操作,我們通常將不可拆分的操作稱為原子操作 而i i 1需要先在主存中取得i的值,之後複製到快取記憶體之中,cpu再從快取記憶體中讀取並計算之後存入快取記憶體,最後把值再存入記憶體中...

Volatile關鍵字解析

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