Java并發(fā)之三:并發(fā)概述

線程安全是一個(gè)比較復(fù)雜的概念嫌吠。當(dāng)多個(gè)線程訪問某個(gè)類時(shí),不受運(yùn)行環(huán)境的調(diào)度方式和這些線程的交替執(zhí)行順序的影響掺炭,也不需要額外的同步,這個(gè)類都能表現(xiàn)出正確的行為凭戴,那么就認(rèn)為它是線程安全的涧狮。常見的并發(fā)編程要么是用得太少未能發(fā)揮計(jì)算能力,要么就是使用不當(dāng)么夫,帶來極大的風(fēng)險(xiǎn)者冤。

線程安全的兩個(gè)特性,原子性(atomicity)和?可見性(visibility)档痪。

原子性就是指對(duì)數(shù)據(jù)的操作是一個(gè)獨(dú)立的涉枫、不可分割的整體。如果一次操作對(duì)應(yīng)一條操作系統(tǒng)指令腐螟,這樣肯定可以能保證原子性愿汰。但是很多操作不能通過一條指令就完成困后。int++?就是一個(gè)典型的非原子操作 ,它對(duì)應(yīng)的是三個(gè)動(dòng)作:取值衬廷、在原值+1摇予、寫回。在并發(fā)環(huán)境下吗跋,往往在第二步就會(huì)遇到問題侧戴,原值已經(jīng)被其他線程修改,當(dāng)前線程仍舊將過時(shí)的“原值”+1后寫回跌宛,導(dǎo)致得到一個(gè)無法預(yù)期的結(jié)果酗宋。非原子操作都存在線程安全問題。要保證組合操作的原子性疆拘,有三種方式: synchronized 蜕猫、 Lock 、非阻塞算法(如CAS入问,比較并交換)丹锹。

要理解可見性,需要先對(duì)JVM的內(nèi)存模型有一定的了解芬失。簡(jiǎn)單來說楣黍,就是每個(gè)線程有私有的工作內(nèi)存,變量會(huì)從共享內(nèi)存拷貝過來棱烂,運(yùn)算動(dòng)作只能針對(duì)工作內(nèi)存中的變量副本進(jìn)行租漂,完成后再將結(jié)果刷回共享內(nèi)存。在并發(fā)環(huán)境下颊糜,如果多條線程同時(shí)操作一個(gè)共享變量的不同副本哩治,某條線程對(duì)變量副本的修改結(jié)果,需要一個(gè)機(jī)制來確保其他線程能“看見”(并刷新自己的變量副本)修改后的最新值衬鱼。

往下討論之前业筏,建議先了解以下兩個(gè)主題:
1、Java并發(fā)之一:Java內(nèi)存模型?
2鸟赫、Java并發(fā)之二:JVM視角下的volatile

為了滿足原子性蒜胖、可見性,Java提供了四種不同的實(shí)現(xiàn):volatile抛蚤、原子類(Atomic)台谢、同步(synchronized)、鎖岁经。

volatile是JVM提供的最輕量級(jí)的同步機(jī)制朋沮。volatile提供單個(gè)field的內(nèi)存同步控制,synchronized則提供整個(gè)臨界區(qū)(代碼塊/方法)的同步控制缀壤。volatile?確保了此變量對(duì)所有線程的實(shí)時(shí)可見性樊拓。普通變量做不到這一點(diǎn)纠亚,普通變量的值在線程間傳遞是異步的,需要通過主內(nèi)存來完成骑脱。但 volatile?只提供了讀寫操作的原子性菜枷,沒提供組合操作的原子性(如依賴原值的 int ++ )。正確地運(yùn)用 volatile?必須考慮它的適用場(chǎng)景:運(yùn)算結(jié)果并不依賴變量的當(dāng)前值叁丧,或者能夠確保只有單一線程修改變量的值啤誊。

原子變量類可以認(rèn)為是?volatile?變量的泛化,它主要通過volatile和硬件支持的CAS算法來支持原子條件的比較并設(shè)置更新拥娄。原子變量類的另一個(gè)更重要的用途是構(gòu)建高效的非阻塞算法蚊锹。非阻塞算法用底層的原子機(jī)器指令代替鎖來確保數(shù)據(jù)在并發(fā)訪問中的一致性。與基于鎖的方案相比稚瘾,非阻塞算法在設(shè)計(jì)和實(shí)現(xiàn)上要復(fù)雜得多牡昆,但它的可伸縮性和活躍性上擁有較大優(yōu)勢(shì)。

同步(synchronized)摊欠,每個(gè)對(duì)象或類有一個(gè)隱式鎖丢烘,每次進(jìn)入synchronized臨界區(qū)時(shí)獲取或阻塞等待該鎖,退出時(shí)釋放鎖些椒。隱式鎖是互斥鎖播瞳,每次只能有一個(gè)線程獲取,未釋放之前其他線程要么阻塞等待直到對(duì)方釋放免糕,要么放棄赢乓。早期的 synchronized 實(shí)現(xiàn)很重,性能不佳石窑。Java 5/6引入鎖升級(jí)的機(jī)制進(jìn)行了優(yōu)化牌芋。此外,synchronized?也有不少功能性的限制 —— 它無法中斷一個(gè)正在等候獲得鎖的線程松逊,也無法通過輪詢得到鎖躺屁。對(duì)此,Java在JUC包中引入了Lock?框架经宏。

Lock?框架?是同步的兼容替代品楼咳,提供了與synchronized關(guān)鍵字類似的同步功能。Lock在使用時(shí)需要顯式地獲取和釋放鎖烛恤。雖然缺少了隱式鎖的便捷性, 但是卻擁有了鎖獲取與釋放的可操作性余耽、 可中斷的獲取鎖以及超時(shí)獲取鎖等多種synchronized關(guān)鍵字所不具備的同步特性缚柏,允許編程人員對(duì)鎖管理進(jìn)行更細(xì)致的控制。Lock接口的實(shí)現(xiàn)基本都是通過聚合了一個(gè)同步器的子類來完成線程訪問控制的碟贾。說到同步器币喧,就要去了解AQS(AbstractQueuedSychronizer)轨域,AQS與CAS構(gòu)成了JUC包的核心。仔細(xì)分析JUC包的源代碼實(shí)現(xiàn)杀餐,會(huì)發(fā)現(xiàn)一個(gè)通用的實(shí)現(xiàn)模式:

首先干发,聲明共享變量為volatile;
然后史翘,使用CAS的原子條件更新來實(shí)現(xiàn)線程之間的同步枉长;
同時(shí),利用volatile的讀/寫和CAS配合實(shí)現(xiàn)線程之間的通信琼讽。

AQS必峰、非阻塞數(shù)據(jù)結(jié)構(gòu)和原子變量類,這些基礎(chǔ)類都是使用這種模式來實(shí)現(xiàn)的钻蹬,而高層類又是依賴于這些基礎(chǔ)類來實(shí)現(xiàn)的吼蚁。

java.util.concurrent?包實(shí)現(xiàn)示意圖

以上這些內(nèi)容,再加上線程創(chuàng)建(Thread/Runnable/Callable)问欠、運(yùn)行管理(Executor框架)肝匆、容器(阻塞隊(duì)列、線程安全集合)等顺献,這就是Java并發(fā)機(jī)制的索驥圖了旗国。


參考:
1、《Java并發(fā)編程實(shí)戰(zhàn)》Brian Goetz等人
2滚澜、《Java思想與實(shí)踐》Brian Goetz?
3粗仓、JAVA CAS原理深度分析

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市设捐,隨后出現(xiàn)的幾起案子借浊,更是在濱河造成了極大的恐慌,老刑警劉巖萝招,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚂斤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡槐沼,警方通過查閱死者的電腦和手機(jī)曙蒸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岗钩,“玉大人纽窟,你說我怎么就攤上這事〖嫦牛” “怎么了臂港?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我审孽,道長(zhǎng)县袱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任佑力,我火速辦了婚禮式散,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘打颤。我一直安慰自己暴拄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布瘸洛。 她就那樣靜靜地躺著揍移,像睡著了一般。 火紅的嫁衣襯著肌膚如雪反肋。 梳的紋絲不亂的頭發(fā)上那伐,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音石蔗,去河邊找鬼罕邀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛养距,可吹牛的內(nèi)容都是我干的诉探。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼棍厌,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肾胯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耘纱,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤敬肚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后束析,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艳馒,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年员寇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弄慰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝶锋,死狀恐怖陆爽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扳缕,我是刑警寧澤墓陈,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布恶守,位于F島的核電站,受9級(jí)特大地震影響贡必,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜庸毫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一仔拟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飒赃,春花似錦利花、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蔫慧,卻和暖如春挠乳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姑躲。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國打工睡扬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人黍析。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓卖怜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親阐枣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子马靠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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