java并發(fā)編程要點

Java并發(fā)問題主要有三個核心概念:原子性,可見性梅屉,順序性值纱。

原子性

并發(fā)問題的原子性的概念和數(shù)據(jù)庫事務(wù)的原子性是一樣的:一個操作的多個步驟要么一起生效,要么一起回滾坯汤。
java自帶的并發(fā)控制的手段中虐唠,可以保障原子性的有:

  • synchronized 關(guān)鍵字
  • CAS
可見性

可見性的問題是指當變量被多個線程使用時,一個線程對其作出的修改操作惰聂,是否后續(xù)其他線程讀的時候能馬上讀到修改后的值疆偿。可見性問題的產(chǎn)生是因為CPU為了加速數(shù)據(jù)讀取讀取的速度庶近,采用了多級的告訴緩存翁脆。
java中保障可見性的手段有

  • synchronized關(guān)鍵字
  • volidate關(guān)鍵字
順序性

順序指的是代碼的執(zhí)行順序眷蚓,順序性指的是java編譯器和CPU鼻种,在保障單個線程執(zhí)行的時代碼的邏輯結(jié)果不變的前提下,可能會對代碼執(zhí)行順序的作出的一些改變(優(yōu)化)沙热。代碼塊在單線程執(zhí)行的情況下叉钥,不管順序怎么變,jvm一定會保證其邏輯不變篙贸,但是多個線程的情況下如果發(fā)生了重排序投队,則局部的邏輯可能是沒變,單是全局的邏輯已經(jīng)有問題了爵川,比如下面的代碼塊

class BadlyOrdered {  
  boolean a = false;  
  boolean b = false;  
  void threadOne() {  
    a = true;  
    b = true;  
  }  

  boolean threadTwo() {  
    boolean r1 = b; // sees true  
    boolean r2 = a; // sees false  
    return r1 && !r2; // returns true  
  }  
}  

方法threadOne在單線程執(zhí)行的情況下敷鸦,不管順序怎么變,其最終的結(jié)果都是a和b都賦值為true寝贡。但是如果是多個線程扒披,線程1執(zhí)行方法threadOne,線程2執(zhí)行方法threadTwo圃泡,即使不考慮可見性的問題碟案,因為threadOne的執(zhí)行順序被排序,所以b的值得先被賦值為true颇蜡,然后線程2讀到了b=true和a=false价说,最后返回的結(jié)果將是true。
那么怎么解決多線程情況下风秤,順序性帶來的不確定問題呢鳖目。一種方法是在編碼時顯示使用synchronized關(guān)鍵,做到同一時間只有1個線程能操作共享的數(shù)據(jù)缤弦。另外一個方法運用jvm自帶的happens-before規(guī)則疑苔。

happens-before

happens-before規(guī)則的描述如下

Happens-Before Relationship : Two actions can be ordered by a happens-before relationship.If one action happens before another, then the first is visible to and ordered before the second.

可見,happens-before規(guī)則同時對可見性和順序產(chǎn)生的了影響。happens-before這個名稱感覺還是挺有歧義的惦费,從"before"這個字眼上看兵迅,以為它定義的是順序性,其實"before"描述的是可見性的"before"薪贫。而順序性恍箭,并不能簡單的從字面描述去理解。比如瞧省,java規(guī)范定義了多條滿足的happens-before規(guī)則扯夭,有一條是:

A write to a volatile field happens-before every subsequent read of that volatile.

它的"before"的定義,不能簡單理解為對一個volatile變量的寫操作發(fā)生在對其讀操作之前鞍匾。一個線程寫交洗,一個線程讀,jvm可不知道哪個會先執(zhí)行到橡淑。這里的"before"是可見性的before构拳,也就是,一個volatile變量的寫操作以及其后面的操作梁棠,對另外一個線程的發(fā)生在這之后的volatile變量的讀操作以及之后的操作可見置森。
而這條規(guī)則,對順序性的真正的影響是:

  • 禁止把volatile寫之前的行為與它重排序
  • 禁止把volatile讀之后的行為與它重排序

對于上面的示例程序符糊,只要把變臉b用volatile關(guān)鍵字修飾凫海,那threadOne方法就不會發(fā)生重排序了。也就是說happens-before規(guī)則也規(guī)定哪些類型的操作之間男娄,編譯器和CPU不能對其進行重排序行贪,編程的時候只要利用這些內(nèi)置的規(guī)則,就能消除重排序在多線程環(huán)境下的問題模闲。
總結(jié)來說建瘫,順序性是java為了單線程執(zhí)行的時候做的優(yōu)化,但是它會在多線程環(huán)境下帶來問題围橡,并且這些問題基本是不能在編碼階段做理論分析的暖混。為了解決這個問題,java又自己內(nèi)置了一些規(guī)則(happens-before規(guī)則)對重排序做了一些限制翁授,多線程編程的時候拣播,只要利用這些規(guī)則,確保我們關(guān)心的關(guān)鍵點不會發(fā)生重排序收擦,也就保證了程序的正確性贮配。

Lock接口

我們知道Lock是jdk提供的并發(fā)控制工具包,使用Lock也能保證java并發(fā)的三個重要特性的塞赂。但是需要說的Lock只是一個工具包泪勒,它提供的保障都是依賴jvm提供的更底層的機制來保障的

  • 可見性: 是對實現(xiàn)中的鎖變量使用volidate關(guān)鍵字,然后依賴volidate帶來的happen-before特性,保障加鎖和解鎖之間的修改對其他線程可見的
  • 原子性:Lock本身的加鎖解鎖這兩個行為的原子性是通過CAS操作保障的圆存,而加鎖之后的行為的原子性叼旋,是通過控制同一時間只能由1個線程執(zhí)行,邏輯保障的
  • 順序性: 同原子性沦辙,也是通過控制同一時間只能由1個線程執(zhí)行的保障的
總結(jié)
原子性 可見性 順序性
sychronized 保證 保證 保證
volatile 不保證 保證 部分保證
CAS操作 保證 不保證 不保證
Lock工具類 保證 保證 保證

####### refer
http://www.infoq.com/cn/articles/java-memory-model-2
http://ifeve.com/easy-happens-before/
http://blog.csdn.net/admiral_dota/article/details/50489882

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夫植,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子油讯,更是在濱河造成了極大的恐慌详民,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陌兑,死亡現(xiàn)場離奇詭異沈跨,居然都是意外死亡,警方通過查閱死者的電腦和手機兔综,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門饿凛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人邻奠,你說我怎么就攤上這事笤喳∥樱” “怎么了碌宴?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蒙畴。 經(jīng)常有香客問我贰镣,道長,這世上最難降的妖魔是什么膳凝? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任碑隆,我火速辦了婚禮,結(jié)果婚禮上蹬音,老公的妹妹穿的比我還像新娘上煤。我一直安慰自己,他們只是感情好著淆,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布劫狠。 她就那樣靜靜地躺著,像睡著了一般永部。 火紅的嫁衣襯著肌膚如雪独泞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天苔埋,我揣著相機與錄音懦砂,去河邊找鬼。 笑死,一個胖子當著我的面吹牛荞膘,可吹牛的內(nèi)容都是我干的罚随。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼羽资,長吁一口氣:“原來是場噩夢啊……” “哼毫炉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起削罩,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤瞄勾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弥激,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进陡,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年微服,在試婚紗的時候發(fā)現(xiàn)自己被綠了趾疚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡以蕴,死狀恐怖糙麦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丛肮,我是刑警寧澤赡磅,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布缭嫡,位于F島的核電站曹仗,受9級特大地震影響昧旨,放射性物質(zhì)發(fā)生泄漏陷虎。R本人自食惡果不足惜上祈,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一忽肛、第九天 我趴在偏房一處隱蔽的房頂上張望温鸽。 院中可真熱鬧寄月,春花似錦诽里、人聲如沸袒餐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灸眼。三九已至,卻和暖如春豌汇,著一層夾襖步出監(jiān)牢的瞬間幢炸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工拒贱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宛徊,地道東北人佛嬉。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像闸天,于是被迫代替她去往敵國和親暖呕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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