(轉(zhuǎn)載)Java CAS 和 synchronized 和 Lock

原文鏈接:Java CAS 和 synchronized 和 Lock - CSDN博客

CAS 機(jī)制

適用場景:樂觀認(rèn)為并發(fā)不高侈询,不需要阻塞舌涨,可以不上鎖。?

特點(diǎn):不斷比較更新扔字,直到成功囊嘉。

缺點(diǎn):高并發(fā)cpu壓力大;ABA問題革为。

ABA問題:?

CAS機(jī)制生效的前提是扭粱,取出內(nèi)存中某時(shí)刻的數(shù)據(jù),而在下時(shí)刻比較并替換震檩。?

如果在比較之前琢蛤,數(shù)據(jù)發(fā)生了變化蜓堕,例如:A->B->A,即A變?yōu)锽然后又變化A博其,那么這個(gè)數(shù)據(jù)還是發(fā)生了變化套才,但是CAS還是會(huì)成功。

Java中CAS機(jī)制使用版本號(hào)進(jìn)行對(duì)比慕淡,避免ABA問題霜旧。

synchronized

適用場景:悲觀認(rèn)為并發(fā)很高,需要阻塞儡率,需要上鎖。

特點(diǎn):語言層面的優(yōu)化以清,鎖粗化儿普、偏向鎖、輕量鎖等等掷倔;可讀性高眉孩。

ReentrantLock 和 Atomic類

以上兩種并發(fā)工具都使用了CAS機(jī)制。?

在并發(fā)不高競爭不激烈時(shí)候勒葱,性能略低于synchronized浪汪;相反,并發(fā)高競爭激烈時(shí)候凛虽,性能高于synchronized死遭。

ReentrantLock相對(duì)于synchronized:

ReentrantLock等待可中斷,synchronized不可以凯旋。

ReentrantLock需要手動(dòng)釋放鎖呀潭,synchronized不需要。

ReentrantLock可支持公平非公平鎖至非,synchronized只支持非公平鎖钠署。

ReentrantLock沒有語言層面的優(yōu)化,底層實(shí)現(xiàn)機(jī)制AQS和CAS荒椭,synchronized有優(yōu)化谐鼎。

ReentrantLock可重入鎖,synchronized不可重入趣惠,可能導(dǎo)致死鎖狸棍。

ReentrantLock支持讀寫鎖,可以提高高并發(fā)讀操作信卡。

synchronized由操作系統(tǒng)支持隔缀,涉及內(nèi)核態(tài)和用戶態(tài)的上下文切換,并發(fā)高時(shí)切換開銷非常大傍菇。

ReentrantLock(AQS)依賴volatile int變量標(biāo)示鎖狀態(tài)猾瘸,結(jié)構(gòu)為雙向鏈表的等待隊(duì)列,通過(cas+死循環(huán))更改鎖狀態(tài),一旦更新成功牵触,標(biāo)示競爭到鎖淮悼。

AQS釋放鎖:?

通過cas改變狀態(tài)

private void doReleaseShared() {

? ? ? ? /*

? ? ? ? * Ensure that a release propagates, even if there are other

? ? ? ? * in-progress acquires/releases.? This proceeds in the usual

? ? ? ? * way of trying to unparkSuccessor of head if it needs

? ? ? ? * signal. But if it does not, status is set to PROPAGATE to

? ? ? ? * ensure that upon release, propagation continues.

? ? ? ? * Additionally, we must loop in case a new node is added

? ? ? ? * while we are doing this. Also, unlike other uses of? ? ? ? * unparkSuccessor, we need to know if CAS to reset status

? ? ? ? * fails, if so rechecking.

? ? ? ? */

? ? ? ? for (;;) {

? ? ? ? ? ? Node h = head;

? ? ? ? ? ? if (h != null && h != tail) {

? ? ? ? ? ? ? ? int ws = h.waitStatus;

? ? ? ? ? ? ? ? if (ws == Node.SIGNAL) {

? ? ? ? ? ? ? ? ? ? if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))

? ? ? ? ? ? ? ? ? ? ? ? continue;? ? ? ? ? ? // loop to recheck cases

? ? ? ? ? ? ? ? ? ? unparkSuccessor(h);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else if (ws == 0 &&

? ? ? ? ? ? ? ? ? ? ? ? !compareAndSetWaitStatus(h, 0, Node.PROPAGATE))

? ? ? ? ? ? ? ? ? ? continue;? ? ? ? ? ? ? ? // loop on failed CAS

? ? ? ? ? ? }

? ? ? ? ? ? if (h == head)? ? ? ? ? ? ? ? ? // loop if head changed

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? }

獲取鎖:?

如果獲取到鎖,設(shè)為頭節(jié)點(diǎn)揽思,否則一直自旋等待袜腥,在高并發(fā)時(shí),可以避免大量鎖競爭的上下文切換钉汗,降低線程切換開銷羹令。

private void doAcquireInterruptibly(int arg)

? ? ? ? throws InterruptedException {

? ? ? ? final Node node = addWaiter(Node.EXCLUSIVE);

? ? ? ? boolean failed = true;

? ? ? ? try {

? ? ? ? ? ? for (;;) {

? ? ? ? ? ? ? ? final Node p = node.predecessor();

? ? ? ? ? ? ? ? if (p == head && tryAcquire(arg)) {

? ? ? ? ? ? ? ? ? ? setHead(node);

? ? ? ? ? ? ? ? ? ? p.next = null; // help GC? ? ? ? ? ? ? ? ? ? failed = false;

? ? ? ? ? ? ? ? ? ? return;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (shouldParkAfterFailedAcquire(p, node) &&

? ? ? ? ? ? ? ? ? ? parkAndCheckInterrupt())

? ? ? ? ? ? ? ? ? ? throw new InterruptedException();

? ? ? ? ? ? }

? ? ? ? } finally {

? ? ? ? ? ? if (failed)

? ? ? ? ? ? ? ? cancelAcquire(node);

? ? ? ? }

? ? }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市损痰,隨后出現(xiàn)的幾起案子福侈,更是在濱河造成了極大的恐慌,老刑警劉巖卢未,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肪凛,死亡現(xiàn)場離奇詭異,居然都是意外死亡辽社,警方通過查閱死者的電腦和手機(jī)伟墙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滴铅,“玉大人戳葵,你說我怎么就攤上這事『撼祝” “怎么了譬淳?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盹兢。 經(jīng)常有香客問我邻梆,道長,這世上最難降的妖魔是什么绎秒? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任浦妄,我火速辦了婚禮,結(jié)果婚禮上见芹,老公的妹妹穿的比我還像新娘剂娄。我一直安慰自己,他們只是感情好玄呛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布阅懦。 她就那樣靜靜地躺著,像睡著了一般徘铝。 火紅的嫁衣襯著肌膚如雪耳胎。 梳的紋絲不亂的頭發(fā)上惯吕,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音怕午,去河邊找鬼废登。 笑死,一個(gè)胖子當(dāng)著我的面吹牛郁惜,可吹牛的內(nèi)容都是我干的堡距。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼兆蕉,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼羽戒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虎韵,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤半醉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后劝术,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呆奕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年行贪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愕难。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蓄氧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情咒唆,我是刑警寧澤硼补,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站拇勃,受9級(jí)特大地震影響四苇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜方咆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一月腋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瓣赂,春花似錦榆骚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苫纤,卻和暖如春碉钠,著一層夾襖步出監(jiān)牢的瞬間纲缓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工放钦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留色徘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓操禀,卻偏偏與公主長得像褂策,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子颓屑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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