精通Java中的volatile關鍵字

在一些開源的框架的源碼當中時不時都可以看到volatile這個關鍵字,最近特意學習一下volatile關鍵字的使用方法效诅。

很多資料中是這樣介紹volatile關鍵字的:

volatile是輕量級的synchronized,它在多處理器開發(fā)中保證了共享變量的“可見性”惨奕∨置耄可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值惋增。

文字不太好理解,通過例子來理解改鲫。

1诈皿、例子

首先看一個沒有使用volatile關鍵字例子:

package com.swnote.java;/**

* volatile測試例子

*

* @author lzj

* @date [2019-04-47]

*/publicclassVolatileTest{private boolean flag;? ? public staticvoidmain(String[] args) {? ? ? ? VolatileTest test =newVolatileTest();? ? ? ? test.test();? ? }? ? publicvoidtest() {newThread(() -> {try{? ? ? ? ? ? ? ? Thread.sleep(1000L);? ? ? ? ? ? }catch(InterruptedException e) {? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? }? ? ? ? ? ? flag =true;? ? ? ? }).start();newThread(() -> {while(true) {if(flag) {? ? ? ? ? ? ? ? ? ? System.out.println("thread flag = "+ flag);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }).start();? ? }}

該例子中定義了一個flag共享變量,test方法里面開啟了兩個線程像棘,第一個線程在等待1秒中后修改共享變量flag的值為true稽亏,第二個線程通過循環(huán)判斷flag的值,當flag的值為true時缕题,輸出內容截歉。

此時有兩種猜想:

執(zhí)行后,可以看到輸出內容避除,即說明第二個線程能夠感知到第一個線程對共享變量flag的修改

執(zhí)行后怎披,沒有任務內容,即說明第二個線程無法感知到第一個線程對共享變量flag的修改

然后執(zhí)行結果為:

沒有任務的輸出內容瓶摆,即證明了此時這樣情況下第二個線程無法感知到第一個線程對共享變量flag的修改的

現(xiàn)在修改一下例子凉逛,即為flag變量加上volatile關鍵字,即:

privatevolatilebooleanflag;

然后再運行群井,此時結果為:

此時就有內容輸出了状飞,說明加上volatile關鍵字后,第二個線程可以感知到第一個線程對共享變量flag的修改的,這就是上面概念中所說的volatile在多處理器開發(fā)中保證了共享變量的“可見性”诬辈。

進群:697699179可以獲取Java各類入門學習資料酵使!

這是我的微信公眾號【編程study】各位大佬有空可以關注下,每天更新Java學習方法焙糟,感謝口渔!

學習中遇到問題有不明白的地方,推薦加小編Java學習群:697699179內有視頻教程 穿撮,直播課程 缺脉,等學習資料,期待你的加入

2悦穿、原理

通過上面的例子證明了volatile在多處理器開發(fā)中保證了共享變量的“可見性”攻礼,那它是怎么實現(xiàn)的呢?

這時就得介紹一下Java的內存模型了栗柒,首先看如下示意圖:

Java內存模型是如上面所示的:

共享變量存儲在主內存中礁扮,每個線程都有一個私有的本地內存,本地內存保存了被該線程使用到的主內存的副本拷貝瞬沦,線程對變量的所有操作都必須在自己的本地內存中進行太伊,而不能直接讀寫主內存中的變量。

根據(jù)此理解蛙埂,上述例子的在沒有加volatile時的情況是這樣的:

第一個線程從主內存中獲取共享變量flag的值倦畅,此時值為false遮糖,將該值放到自己的本地內存中绣的,然后對變量進行修改,將值改為true欲账,此時也只是將本地內存中flag的值改為了true屡江,此時還沒有將值同步到主內存中,然后第二線程也是將共享變量flag的值放到自己的本地內存中赛不,而此時flag的值還是為false惩嘉,所以就是一直沒有內容輸出了。

然而加上volatile關鍵字后踢故,第一個線程對flag的修改會強制刷新到主內存中去文黎,同時還會導致其他線程中的本地內存的值會無效,需要重新到主內存獲取殿较,這樣就保證了第一個線程對flag修改后耸峭,第二線程能夠感知到。

3淋纲、注意點

volatile是輕量級的synchronized劳闹,但是它是不能夠代替synchronized的,因為volatile只能保證原子性操作的安全,對于復合操作本涕,volatile是不能保證線程安全的业汰。

例如:

packagecom.swnote.java;/** * 復合操作例子 * *@authorlzj *@date[2019-04-27] */publicclassStatisticTest{privatevolatileintnum =0;publicstaticvoidmain(String[] args){? ? ? ? StatisticTest test =newStatisticTest();? ? ? ? test.statistic();? ? }publicvoidstatistic(){for(inti =0; i <20; i++) {newThread(() -> {? ? ? ? ? ? ? ? num++;? ? ? ? ? ? }).start();? ? ? ? }? ? ? ? System.out.println("num = "+ num);? ? }}

期望的運行結果是20,可是幾乎每次運行結果都是不一樣的菩颖,例如有的結果為:

這是因為num++這個操作不是原子性的样漆,所以即使使用了volatile關鍵字,也是不能保證安全的晦闰。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末氛濒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鹅髓,更是在濱河造成了極大的恐慌舞竿,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窿冯,死亡現(xiàn)場離奇詭異骗奖,居然都是意外死亡,警方通過查閱死者的電腦和手機醒串,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門执桌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芜赌,你說我怎么就攤上這事仰挣。” “怎么了缠沈?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵膘壶,是天一觀的道長。 經(jīng)常有香客問我洲愤,道長颓芭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任柬赐,我火速辦了婚禮亡问,結果婚禮上,老公的妹妹穿的比我還像新娘肛宋。我一直安慰自己州藕,他們只是感情好,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布酝陈。 她就那樣靜靜地躺著床玻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪后添。 梳的紋絲不亂的頭發(fā)上笨枯,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天薪丁,我揣著相機與錄音,去河邊找鬼馅精。 笑死严嗜,一個胖子當著我的面吹牛,可吹牛的內容都是我干的洲敢。 我是一名探鬼主播漫玄,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼压彭!你這毒婦竟也來了睦优?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤壮不,失蹤者是張志新(化名)和其女友劉穎汗盘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體询一,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡隐孽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了健蕊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片菱阵。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缩功,靈堂內的尸體忽然破棺而出晴及,到底是詐尸還是另有隱情,我是刑警寧澤嫡锌,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布虑稼,位于F島的核電站,受9級特大地震影響世舰,放射性物質發(fā)生泄漏动雹。R本人自食惡果不足惜槽卫,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一跟压、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歼培,春花似錦震蒋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至噪窘,卻和暖如春笋庄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工直砂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留菌仁,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓静暂,卻偏偏與公主長得像济丘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子洽蛀,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容