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

image

什么是線程安全?
線程安全,有兩個(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)先級的線程吞噬了低優(yōu)先級的線程的 CPU 時(shí)間片
  2. 理論上來說番官,線程優(yōu)先級高的線程會(huì)比線程優(yōu)先級低的線程獲得更多的執(zhí)行機(jī)會(huì)庐完,但是 java 的線程優(yōu)先級不是絕對出現(xiàn)這樣的效果。
  3. 一般而言:優(yōu)先級高的出現(xiàn)頻率會(huì)比優(yōu)先級低的高很多
  4. 不同的操作系統(tǒng)對線程的優(yōu)先級支持是不同的徘熔,規(guī)定是在 1-10 之間门躯,java 通過 3 個(gè)常量來屏蔽這種操作系統(tǒng)的底層差異化。
  5. 線程被永久阻塞在等待進(jìn)入同步代碼塊的狀態(tài)
  6. 等待的線程永遠(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閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異劳殖,居然都是意外死亡铐尚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門哆姻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來塑径,“玉大人,你說我怎么就攤上這事填具⊥骋ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵劳景,是天一觀的道長誉简。 經(jīng)常有香客問我,道長盟广,這世上最難降的妖魔是什么闷串? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮筋量,結(jié)果婚禮上烹吵,老公的妹妹穿的比我還像新娘。我一直安慰自己桨武,他們只是感情好肋拔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著呀酸,像睡著了一般凉蜂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天窿吩,我揣著相機(jī)與錄音茎杂,去河邊找鬼。 笑死纫雁,一個(gè)胖子當(dāng)著我的面吹牛煌往,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轧邪,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼携冤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闲勺?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤扣猫,失蹤者是張志新(化名)和其女友劉穎菜循,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體申尤,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癌幕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昧穿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勺远。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖时鸵,靈堂內(nèi)的尸體忽然破棺而出胶逢,到底是詐尸還是另有隱情,我是刑警寧澤饰潜,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布初坠,位于F島的核電站,受9級特大地震影響彭雾,放射性物質(zhì)發(fā)生泄漏碟刺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一薯酝、第九天 我趴在偏房一處隱蔽的房頂上張望半沽。 院中可真熱鬧,春花似錦吴菠、人聲如沸者填。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幔托。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間重挑,已是汗流浹背嗓化。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谬哀,地道東北人刺覆。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像史煎,于是被迫代替她去往敵國和親谦屑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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