Java中的volatile 和synchronized

作者: 一字馬胡
轉(zhuǎn)載標(biāo)志 【2017-11-03】

更新日志

日期 更新內(nèi)容 備注
2017-11-03 添加轉(zhuǎn)載標(biāo)志 持續(xù)更新

在進(jìn)行java并發(fā)編程時骡楼,volatile和synchronized的使用是相當(dāng)廣泛的邮弹,為了安全的進(jìn)行并發(fā)編程凑队,學(xué)習(xí)和使用volatile和synchronized也是相當(dāng)有必要的谤辜。

一厉亏、volatile
在java語言中,使用多個線程來訪問共享變量是一種常見的并發(fā)場景榔袋,這就使得多個線程可能同時修改共享變量,那么限制多個線程排他的訪問共享變量就變得非常有必要了铡俐。java提供了多種方式來達(dá)到限制多線程排他的訪問共享變量的方法凰兑,但是代價也是不同的。使用volatile是一種非常輕量級的方式审丘。如果一個變量被聲明為volatile吏够,那么jvm將保證所有線程看到的都是同一個共享變量。為什么不同線程看到的變量可能不一樣呢滩报?因為為了提高處理速度锅知,cpu不直接和內(nèi)存交互,而是首先將內(nèi)存讀取到內(nèi)部緩存(L1,L2等)中脓钾,然后cpu就直接和內(nèi)部緩存通信來提高處理速度售睹。對于具有多個cpu的機(jī)器來說,不同的線程可能都在訪問某個共享變量可训,而不同的線程運(yùn)行在不同的cpu里面昌妹,所以同一個變量可能被緩存在多個cpu內(nèi)部緩存里面,如果沒有volatile來保證共享變量對于多線程是一致的話握截,就可能發(fā)生多個線程訪問到的共享變量具備不同的值飞崖,因為我們不知道cpu會在什么時候?qū)⒕彺娴闹祵懟氐絻?nèi)存中去。
在實現(xiàn)上谨胞,如果對被volatile修飾的共享變量執(zhí)行寫操作的話固歪,JVM就會向cpu發(fā)送一條Lock前綴的指令,cpu將會這個變量所在的緩存行(緩存中可以分配的最小緩存單位)寫回到內(nèi)存中去胯努。但是在多處理器的情況下牢裳,將某個cpu上的緩存行寫回到系統(tǒng)內(nèi)存之后术瓮,其他cpu上該變量的緩存還是舊的,這樣再進(jìn)行后面的操作的時候就會出現(xiàn)問題贰健,所以為了使得所有線程看到的內(nèi)容都是一致的胞四,就需要實現(xiàn)緩存一致性協(xié)議,cpu將會通過監(jiān)控總線上傳遞過來的數(shù)據(jù)來判斷自己的緩存是否過期伶椿,如果過期辜伟,就需要使得緩存失效,如果cpu再來訪問該緩存的時候脊另,就會發(fā)現(xiàn)緩存失效了导狡,這時候就會重新從內(nèi)存加載緩存。
總結(jié)一下偎痛,volatile的實現(xiàn)原則有兩條:
1旱捧、JVM的Lock前綴的指令將使得cpu緩存寫回到系統(tǒng)內(nèi)存中去
2、為了保證緩存一致性原則踩麦,在多cpu的情景下枚赡,一個cpu的緩存回寫內(nèi)存會導(dǎo)致其他的
cpu上的緩存都失效,再次訪問會重新從系統(tǒng)內(nèi)存加載新的緩存內(nèi)容谓谦。

二贫橙、synchronized

相對于volatile,synchronized就顯得比較重量級了反粥。
首先卢肃,我們應(yīng)該知道,在java中才顿,所有的對象都可以作為鎖莫湘。可以分為下面三種情況:
1郑气、普通方法同步幅垮,鎖是當(dāng)前對象
2、靜態(tài)方法同步竣贪,鎖是當(dāng)前類的Class對象
3军洼、普通塊同步,鎖是synchronize里面配置的對象
當(dāng)一個線程試圖訪問同步代碼時演怎,必須要先獲得鎖匕争,退出或者拋出異常時必須要釋放鎖。
JVM基于進(jìn)入和退出Monitor對象來實現(xiàn)方法同步和代碼塊同步爷耀,可以使用monitorenter和monitorexit指令實現(xiàn)甘桑。monitorenter指令是在編譯后插入到同步代碼塊的開始位置,而monitorexit指令則插入到方法結(jié)束和異常處,JVM保證每個monitorenter都有一個monitorexit閾值相對應(yīng)跑杭。線程執(zhí)行到monitorenter的時候铆帽,會嘗試獲得對象所對應(yīng)的monitor的鎖,然后才能獲得訪問權(quán)限德谅,synchronize使用的鎖保存在Java對象頭中爹橱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市窄做,隨后出現(xiàn)的幾起案子愧驱,更是在濱河造成了極大的恐慌,老刑警劉巖椭盏,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件组砚,死亡現(xiàn)場離奇詭異,居然都是意外死亡掏颊,警方通過查閱死者的電腦和手機(jī)糟红,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乌叶,“玉大人盆偿,你說我怎么就攤上這事⊥骰瑁” “怎么了陈肛?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兄裂。 經(jīng)常有香客問我,道長阳藻,這世上最難降的妖魔是什么晰奖? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮腥泥,結(jié)果婚禮上匾南,老公的妹妹穿的比我還像新娘。我一直安慰自己蛔外,他們只是感情好蛆楞,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夹厌,像睡著了一般豹爹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上矛纹,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天臂聋,我揣著相機(jī)與錄音,去河邊找鬼。 笑死孩等,一個胖子當(dāng)著我的面吹牛艾君,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肄方,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼冰垄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了权她?” 一聲冷哼從身側(cè)響起虹茶,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伴奥,沒想到半個月后写烤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拾徙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年洲炊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尼啡。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡暂衡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出崖瞭,到底是詐尸還是另有隱情狂巢,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布书聚,位于F島的核電站唧领,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏雌续。R本人自食惡果不足惜斩个,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望驯杜。 院中可真熱鬧受啥,春花似錦、人聲如沸鸽心。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽顽频。三九已至藤肢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間冲九,已是汗流浹背谤草。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工跟束, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丑孩。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓冀宴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親温学。 傳聞我的和親對象是個殘疾皇子略贮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容