【轉(zhuǎn)】java高并發(fā)鎖的3種實(shí)現(xiàn)

【轉(zhuǎn)】java高并發(fā)鎖的3種實(shí)現(xiàn)

標(biāo)簽:JAVA發(fā)布于 2017-06-01 09:59:50

初級(jí)技巧 - 樂(lè)觀鎖

樂(lè)觀鎖適合這樣的場(chǎng)景:讀不會(huì)沖突孝情,寫會(huì)沖突。同時(shí)讀的頻率遠(yuǎn)大于寫李破。

以下面的代碼為例,悲觀鎖的實(shí)現(xiàn):

Java代碼

publicObject?get(Object?key)?{

synchronized(map)?{

if(map.get(key)?==null)?{

//?set?some?values

}

returnmap.get(key);

}

}

樂(lè)觀鎖的實(shí)現(xiàn):

Java代碼

publicObject?get(Object?key)?{

Object?val?=null;

if((val?=?map.get(key)?==null)?{

//?當(dāng)map取值為null時(shí)再加鎖判斷

synchronized(map)?{

if(val?=?map.get(key)?==null)?{

//?set?some?value?to?map...

}

}

}

returnmap.get(key);

}

中級(jí)技巧 - String.intern()

樂(lè)觀鎖不能很好解決大量寫沖突問(wèn)題,但是如果很多場(chǎng)景下吭产,鎖實(shí)際上只是針對(duì)某個(gè)用戶或者某個(gè)訂單个从。比如一個(gè)用戶必須先創(chuàng)建session脉幢,才能進(jìn)行后面的操作。但是由于網(wǎng)絡(luò)原因嗦锐,創(chuàng)建用戶session的請(qǐng)求和后續(xù)請(qǐng)求幾乎同時(shí)達(dá)到嫌松,而并行線程可能會(huì)先處理后續(xù)請(qǐng)求。一般情況奕污,需要對(duì)用戶sessionMap加鎖萎羔,比如上面的樂(lè)觀鎖。在這種場(chǎng)景下碳默,可以講鎖限定到用戶本身上贾陷,即從原來(lái)的

lock.lock();

int num=storage.get(key);

storage.set(key,num+1);

lock.unlock();

更改為:

lock.lock(key);

int num=storage.get(key);

storage.set(key,num+1);

lock.unlock(key);

這個(gè)比較類似于數(shù)據(jù)庫(kù)表鎖和行鎖的概念,顯然行鎖的并發(fā)能力比表鎖高很多嘱根。

使用String.inter()是這種思路的一種具體實(shí)現(xiàn)髓废。類 String 維護(hù)一個(gè)字符串池。 當(dāng)調(diào)用 intern 方法時(shí)该抒,如果池已經(jīng)包含一個(gè)等于此 String 對(duì)象的字符串(該對(duì)象由 equals(Object) 方法確定)慌洪,則返回池中的字符串∪岜疲可見(jiàn)蒋譬,當(dāng)String相同時(shí),String.intern()總是返回同一個(gè)對(duì)象愉适,因此就實(shí)現(xiàn)了對(duì)同一用戶加鎖犯助。由于鎖的粒度局限于具體用戶,使系統(tǒng)獲得了最大程度的并發(fā)维咸。

Java代碼

publicvoiddoSomeThing(String?uid)?{

synchronized(uid.intern())?{

//?...

}

}

CopyOnWriteMap剂买?

既然說(shuō)到了“類似于數(shù)據(jù)庫(kù)中的行鎖的概念”惠爽,就不得不提一下MVCC,Java中CopyOnWrite類實(shí)現(xiàn)了MVCC瞬哼。Copy On Write是這樣一種機(jī)制婚肆。當(dāng)我們讀取共享數(shù)據(jù)的時(shí)候,直接讀取坐慰,不需要同步较性。當(dāng)我們修改數(shù)據(jù)的時(shí)候,我們就把當(dāng)前數(shù)據(jù)Copy一份副本结胀,然后在這個(gè)副本 上進(jìn)行修改赞咙,完成之后,再用修改后的副本糟港,替換掉原來(lái)的數(shù)據(jù)攀操。這種方法就叫做Copy On Write。

但是秸抚,速和,,JDK并沒(méi)有提供CopyOnWriteMap剥汤,為什么颠放?下面有個(gè)很好的回答,那就是已經(jīng)有了ConcurrentHashMap秀姐,為什么還需要CopyOnWriteMap慈迈?

Fredrik Bromee 寫道

I guess this depends on your use case, but why would you need a CopyOnWriteMap when you already have a ConcurrentHashMap?

For a plain lookup table with many readers and only one or few updates it is a good fit.

Compared to a copy on write collection:

Read concurrency:

Equal to a copy on write collection. Several readers can retrieve elements from the map concurrently in a lock-free fashion.

Write concurrency:

Better concurrency than the copy on write collections that basically serialize updates (one update at a time). Using a concurrent hash map you have a good chance of doing several updates concurrently. If your hash keys are evenly distributed.

If you do want to have the effect of a copy on write map, you can always initialize a ConcurrentHashMap with a concurrency level of 1.

高級(jí)技巧 - 類ConcurrentHashMap

String.inter()的缺陷是類 String 維護(hù)一個(gè)字符串池是放在JVM perm區(qū)的若贮,如果用戶數(shù)特別多省有,導(dǎo)致放入字符串池的String不可控,有可能導(dǎo)致OOM錯(cuò)誤或者過(guò)多的Full GC谴麦。怎么樣能控制鎖的個(gè)數(shù)蠢沿,同時(shí)減小粒度鎖呢?直接使用Java ConcurrentHashMap匾效?或者你想加入自己更精細(xì)的控制舷蟀?那么可以借鑒ConcurrentHashMap的方式,將需要加鎖的對(duì)象分為多個(gè)bucket面哼,每個(gè)bucket加一個(gè)鎖野宜,偽代碼如下:

Java代碼

Map?locks?=newMap();

List?lockKeys?=newList();

for(intnumber?:1-10000)?{

Object?lockKey?=newObject();

lockKeys.add(lockKey);

locks.put(lockKey,newObject());

}

publicvoiddoSomeThing(String?uid)?{

Object?lockKey?=?lockKeys.get(uid.hash()?%?lockKeys.size());

Object?lock?=?locks.get(lockKey);

synchronized(lock)?{

//?do?something

}

}

原文請(qǐng)參考:http://www.roncoo.com/article/detail/128506

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市魔策,隨后出現(xiàn)的幾起案子匈子,更是在濱河造成了極大的恐慌,老刑警劉巖闯袒,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虎敦,死亡現(xiàn)場(chǎng)離奇詭異游岳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)其徙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門胚迫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人唾那,你說(shuō)我怎么就攤上這事访锻。” “怎么了闹获?”我有些...
    開(kāi)封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵朗若,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我昌罩,道長(zhǎng)哭懈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任茎用,我火速辦了婚禮遣总,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轨功。我一直安慰自己旭斥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布古涧。 她就那樣靜靜地躺著垂券,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羡滑。 梳的紋絲不亂的頭發(fā)上菇爪,一...
    開(kāi)封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音柒昏,去河邊找鬼凳宙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛职祷,可吹牛的內(nèi)容都是我干的氏涩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼有梆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼是尖!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起泥耀,我...
    開(kāi)封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饺汹,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后爆袍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體首繁,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡作郭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弦疮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夹攒。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胁塞,靈堂內(nèi)的尸體忽然破棺而出咏尝,到底是詐尸還是另有隱情,我是刑警寧澤啸罢,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布编检,位于F島的核電站,受9級(jí)特大地震影響扰才,放射性物質(zhì)發(fā)生泄漏允懂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一衩匣、第九天 我趴在偏房一處隱蔽的房頂上張望蕾总。 院中可真熱鬧,春花似錦琅捏、人聲如沸生百。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蚀浆。三九已至,卻和暖如春搜吧,著一層夾襖步出監(jiān)牢的瞬間市俊,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工赎败, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秕衙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓僵刮,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鹦牛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搞糕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法曼追,內(nèi)部類的語(yǔ)法窍仰,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法礼殊,線程的語(yǔ)...
    子非魚_t_閱讀 31,596評(píng)論 18 399
  • 個(gè)人筆記驹吮,方便自己查閱使用 Contents Java LangAssignment, ReferenceData...
    freenik閱讀 1,370評(píng)論 0 6
  • 從三月份找實(shí)習(xí)到現(xiàn)在针史,面了一些公司,掛了不少碟狞,但最終還是拿到小米啄枕、百度、阿里族沃、京東频祝、新浪、CVTE脆淹、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,206評(píng)論 11 349
  • 昨天開(kāi)始常空,萌寶就開(kāi)始了一段人生新旅程,背著小書包開(kāi)始上學(xué)啦盖溺。目前為止漓糙,前方捷報(bào)頻傳,從第一天開(kāi)始就乖乖滴和爺爺奶奶...
    小多媛媛閱讀 134評(píng)論 0 0
  • 淮濱縣
    山登絕頂閱讀 222評(píng)論 0 0