【并發(fā)編程技術(shù)】在并發(fā)編程模式下進(jìn)行線程安全以及活躍性問題簡析

什么是線程安全壤巷?

線程安全胧华,有兩個(gè)重要的特征說明:“共享”和“可變”宙彪。

  • 共享是指可以被多個(gè)線程同時(shí)訪問释漆;

  • 可變是指變量的值在生命周期內(nèi)是可以變化的;

如何實(shí)現(xiàn)線程安全

  • 一個(gè)對象是否需要線程安全的檀训,取決于它是否被多個(gè)線程訪問享言;

  • 如何保證一個(gè)對象的線程安全览露,則需要采用同步機(jī)制來協(xié)同對對象可變狀態(tài)的訪問;

  • 給線程安全下一個(gè)明確的定義:當(dāng)多個(gè)線程訪問這個(gè)對象或者資源時(shí)命锄,如果這個(gè)對象或資源始終都能表現(xiàn)出數(shù)據(jù)的一致性的狀態(tài)脐恩,那么就稱這個(gè)對象或者資源是線程安全的侦讨;

數(shù)據(jù)資源的有無狀態(tài)化

  • 無狀態(tài)的對象一定是線程安全的。

  • 有狀態(tài)的對象崇猫,多線程環(huán)境下诅炉,多個(gè)線程共享資源,且進(jìn)行的不是原子性操作涕烧,這個(gè)時(shí)候就要考慮線程的安全控制問題

比如:count++澈魄,其實(shí)是不具備原子性的痹扇,因?yàn)檫@個(gè)步驟實(shí)際會(huì)被拆分為三個(gè)步驟鲫构,即 讀取结笨、修改和寫入炕吸,而這三個(gè)步驟有可能在某個(gè)時(shí)刻因CPU時(shí)間片的切換問題勉痴,而只執(zhí)行其中一兩個(gè)步驟蒸矛,這就不具備原子性。

image

原子化能力支持

在Java中斩祭,為了解決這個(gè)問題摧玫,java.util.concurrent.atomic包提供了很多的類蚊伞,來保證數(shù)據(jù)操作的原子性时迫,比如我們之前的程序可以修改為

  • 基本數(shù)據(jù)類型 AtomicInteger

  • 數(shù)組類型 AtomicIntegerArray

AtomicInteger integer = new AtomicInteger(0);
integer.incrementAndGet()

內(nèi)部的原理是采用了CAS機(jī)制

那么什么是CAS機(jī)制?

CAS有人翻譯為Compare And Set或Compare And Swap都是正確的掠拳。

多線程并發(fā)執(zhí)行的狀態(tài)下溺欧,鎖的狀態(tài)改變,基本都是使用CAS原理绑改,它有一個(gè)比較別扭的叫法“CPU硬件同步原語”座哩,算法是基于CPU硬件的,原子性操作柏靶,不會(huì)被其他線程打斷弃理。

CAS的算法,比較當(dāng)前值和期望的值是否相等屎蜓,如果相等痘昌,則將當(dāng)前值賦予一個(gè)新值。

再比如修改一個(gè)Boolean的類型的變量的值炬转,我們也可以采用

private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public void lock(){
    //期望是false辆苔,如果是false,則可以修改為true
    atomicBoolean.compareAndSet(false, true);
}

同步鎖機(jī)制支持

只要程序中存在“先判斷街佑,再更新”磁携,那么就要保證這兩個(gè)操作在一個(gè)原子操作里面歪脏,才能保證線程安全豪硅。

public synchronized int getCount(){
    return count++;
}
Java鎖機(jī)制的一些特點(diǎn)

監(jiān)視鎖砚著、互斥鎖、可重入鎖都是在這個(gè)鎖的特點(diǎn)。

  • 監(jiān)視鎖:java的每一個(gè)對象都可以用來做監(jiān)視鎖,也就是為什么我們的wait、notify方法定義在Object類的原因。

  • 互斥鎖:表示最多只有一個(gè)線程可以持有這把鎖。

  • 可重入鎖:是指當(dāng)線程A請求一個(gè)由線程B持有的鎖時(shí),線程B會(huì)進(jìn)入阻塞狀態(tài)账千;而如果線程A如果再訪問另一段代碼桦山,而這個(gè)代碼的鎖是已經(jīng)被線程A持有的,這個(gè)時(shí)候請求是可以成功的钉凌,這就叫可重入酸纲。

Java鎖機(jī)制的簡單原理

JVM為每個(gè)鎖設(shè)置兩個(gè)屬性疾嗅,獲取計(jì)數(shù)值和所有者線程论悴,當(dāng)計(jì)數(shù)值為0時(shí)玖像,這個(gè)鎖就被認(rèn)為是沒有被任何線程持有,當(dāng)線程請求一個(gè)未被持有的鎖時(shí)乡洼,JVM將記錄鎖的持有者,并且計(jì)數(shù)值+1巴比。

如果同一個(gè)線程再次獲取這個(gè)鎖佣耐,則計(jì)數(shù)值將遞增,而當(dāng)線程退出同步代碼塊時(shí)奸远,計(jì)數(shù)器會(huì)相應(yīng)遞減掖鱼,當(dāng)計(jì)數(shù)值為0戏挡,這個(gè)鎖將被釋放。

活躍性問題

承接上面解決安全性的問題分析,鎖機(jī)制會(huì)存在活躍性問題持际,比如:死鎖,饑餓闷祥,活鎖座泳,這些都是屬于活躍性問題。

死鎖

多個(gè)線程幕与,各自占對方的資源挑势,都不愿意釋放,從而造成死鎖啦鸣,A線程需要等待的鎖被B線程占用潮饱,而B線程需要的等待的鎖被A線程占用,所以相互都不釋放诫给,于是就陷入了死鎖香拉。

饑餓

多個(gè)線程訪問同一個(gè)同步資源,有些線程總是沒有機(jī)會(huì)得到互斥鎖中狂,這種就叫做饑餓凫碌。

出現(xiàn)饑餓的三種情況
  1. 高優(yōu)先級(jí)的線程吞噬了低優(yōu)先級(jí)的線程的CPU時(shí)間片

    • 理論上來說,線程優(yōu)先級(jí)高的線程會(huì)比線程優(yōu)先級(jí)低的線程獲得更多的執(zhí)行機(jī)會(huì)胃榕,但是java的線程優(yōu)先級(jí)不是絕對出現(xiàn)這樣的效果盛险。

    • 一般而言:優(yōu)先級(jí)高的出現(xiàn)頻率會(huì)比優(yōu)先級(jí)低的高很多

    • 不同的操作系統(tǒng)對線程的優(yōu)先級(jí)支持是不同的,規(guī)定是在1-10之間,java通過3個(gè)常量來屏蔽這種操作系統(tǒng)的底層差異化苦掘。

  2. 線程被永久阻塞在等待進(jìn)入同步代碼塊的狀態(tài)

  3. 等待的線程永遠(yuǎn)不被喚醒

建議大家采用公平鎖來代替synchronized這種互斥鎖

活鎖

兩個(gè)人在走廊上碰見泉褐,大家都互相很有禮貌,互相禮讓鸟蜡,A從左到右膜赃,B也從從左轉(zhuǎn)向右,發(fā)現(xiàn)又擋住了地方揉忘,繼續(xù)轉(zhuǎn)換方向跳座,但又碰到了,反反復(fù)復(fù)泣矛,一直沒有機(jī)會(huì)運(yùn)行下去疲眷。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市您朽,隨后出現(xiàn)的幾起案子狂丝,更是在濱河造成了極大的恐慌,老刑警劉巖哗总,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件几颜,死亡現(xiàn)場離奇詭異,居然都是意外死亡讯屈,警方通過查閱死者的電腦和手機(jī)蛋哭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涮母,“玉大人谆趾,你說我怎么就攤上這事∨驯荆” “怎么了沪蓬?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長来候。 經(jīng)常有香客問我跷叉,道長,這世上最難降的妖魔是什么吠勘? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任性芬,我火速辦了婚禮,結(jié)果婚禮上剧防,老公的妹妹穿的比我還像新娘植锉。我一直安慰自己,他們只是感情好峭拘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布俊庇。 她就那樣靜靜地躺著狮暑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辉饱。 梳的紋絲不亂的頭發(fā)上搬男,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音彭沼,去河邊找鬼缔逛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛姓惑,可吹牛的內(nèi)容都是我干的褐奴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼于毙,長吁一口氣:“原來是場噩夢啊……” “哼敦冬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唯沮,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤脖旱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后介蛉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萌庆,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年甘耿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了踊兜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡佳恬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出于游,到底是詐尸還是另有隱情毁葱,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布贰剥,位于F島的核電站倾剿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚌成。R本人自食惡果不足惜前痘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望担忧。 院中可真熱鬧芹缔,春花似錦、人聲如沸瓶盛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芝硬,卻和暖如春蚜点,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拌阴。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工绍绘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人迟赃。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓陪拘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捺氢。 傳聞我的和親對象是個(gè)殘疾皇子藻丢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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