Java多線程同步的五種方法

一骤公、引言

前幾天面試,被大師虐殘了蚂会,好多基礎(chǔ)知識必須得重新拿起來啊淋样。閑話不多說,進入正題胁住。

二趁猴、為什么要線程同步

因為當我們有多個線程要同時訪問一個變量或?qū)ο髸r刊咳,如果這些線程中既有讀又有寫操作時,就會導致變量值或?qū)ο蟮臓顟B(tài)出現(xiàn)混亂儡司,從而導致程序異常椭符。舉個例子徙融,如果一個銀行賬戶同時被兩個線程操作毡熏,一個取100塊砖茸,一個存錢100塊。假設(shè)賬戶原本有0塊碉碉,如果取錢線程和存錢線程同時發(fā)生柴钻,會出現(xiàn)什么結(jié)果呢?取錢不成功垢粮,賬戶余額是100.取錢成功了贴届,賬戶余額是0.那到底是哪個呢?很難說清楚蜡吧。因此多線程同步就是要解決這個問題毫蚓。如果你想學習Java可以來這個群,首先是一二六昔善,中間是五三四元潘,最后是五一九君仆,里面有大量的學習資料可以下載氮帐。

三、不同步時的代碼

Bank.java

package threadTest;

SyncThreadTest.java

package threadTest;

代碼很簡單楞艾,我就不解釋了龄广,看看運行結(jié)果怎樣呢?截取了其中的一部分两入,是不是很亂,有寫看不懂裹纳。

余額不足

四剃氧、使用同步時的代碼

(1)同步方法:

即有synchronized關(guān)鍵字修飾的方法朋鞍。 由于java的每個對象都有一個內(nèi)置鎖滥酥,當用此關(guān)鍵字修飾方法時疏哗,內(nèi)置鎖會保護整個方法。在調(diào)用該方法前禾怠,需要獲得內(nèi)置鎖吗氏,否則就處于阻塞狀態(tài)污尉。

修改后的Bank.java

package threadTest;

再看看運行結(jié)果:

余額不足

瞬間感覺可以理解了吧仿村。

注: synchronized關(guān)鍵字也可以修飾靜態(tài)方法,此時如果調(diào)用該靜態(tài)方法焚志,將會鎖住整個類

(2)同步代碼塊

即有synchronized關(guān)鍵字修飾的語句塊酱酬。被該關(guān)鍵字修飾的語句塊會自動被加上內(nèi)置鎖,從而實現(xiàn)同步

Bank.java代碼如下:

package threadTest;

運行結(jié)果如下:

余額不足

效果和方法一差不多陨界。

注:同步是一種高開銷的操作滔灶,因此應(yīng)該盡量減少同步的內(nèi)容。通常沒有必要同步整個方法,使用synchronized代碼塊同步關(guān)鍵代碼即可免钻。

(3)使用特殊域變量(Volatile)實現(xiàn)線程同步

a.volatile關(guān)鍵字為域變量的訪問提供了一種免鎖機制

b.使用volatile修飾域相當于告訴虛擬機該域可能會被其他線程更新

c.因此每次使用該域就要重新計算,而不是使用寄存器中的值

d.volatile不會提供任何原子操作拆魏,它也不能用來修飾final類型的變量

Bank.java代碼如下:

package threadTest;

運行效果怎樣呢盯桦?

余額不足

是不是又看不懂了,又亂了渤刃。這是為什么呢拥峦?就是因為volatile不能保證原子操作導致的,因此volatile不能代替synchronized卖子。此外volatile會組織編譯器對代碼優(yōu)化略号,因此能不使用它就不適用它吧。它的原理是每次要線程要訪問volatile修飾的變量時都是從內(nèi)存中讀取揪胃,而不是存緩存當中讀取璃哟,因此每個線程訪問到的變量值都是一樣的。這樣就保證了同步喊递。如果你想學習Java可以來這個群,首先是一二六阳似,中間是五三四骚勘,最后是五一九,里面有大量的學習資料可以下載。

(4)使用重入鎖實現(xiàn)線程同步

在JavaSE5.0中新增了一個java.util.concurrent包來支持同步俏讹。ReentrantLock類是可重入当宴、互斥、實現(xiàn)了Lock接口的鎖泽疆, 它與使用synchronized方法和快具有相同的基本行為和語義户矢,并且擴展了其能力。

ReenreantLock類的常用方法有:

ReentrantLock() : 創(chuàng)建一個ReentrantLock實例

lock() : 獲得鎖

unlock() : 釋放鎖

注:ReentrantLock()還有一個可以創(chuàng)建公平鎖的構(gòu)造方法殉疼,但由于能大幅度降低程序運行效率梯浪,不推薦使用

Bank.java代碼修改如下:

package threadTest;

運行效果怎么樣呢?

余額不足

效果和前兩種方法差不多瓢娜。

如果synchronized關(guān)鍵字能滿足用戶的需求挂洛,就用synchronized,因為它能簡化代碼 眠砾。如果需要更高級的功能虏劲,就用ReentrantLock類,此時要注意及時釋放鎖褒颈,否則會出現(xiàn)死鎖柒巫,通常在finally代碼釋放鎖

(5)使用局部變量實現(xiàn)線程同步

Bank.java代碼如下:

package threadTest;

運行效果:

余額不足

看了運行效果,一開始一頭霧水谷丸,怎么只讓存堡掏,不讓取啊淤井?看看ThreadLocal的原理:

如果使用ThreadLocal管理變量布疼,則每一個使用該變量的線程都獲得該變量的副本,副本之間相互獨立币狠,這樣每一個線程都可以隨意修改自己的變量副本游两,而不會對其他線程產(chǎn)生影響。現(xiàn)在明白了吧漩绵,原來每個線程運行的都是一個副本贱案,也就是說存錢和取錢是兩個賬戶,知識名字相同而已止吐。所以就會發(fā)生上面的效果宝踪。

ThreadLocal與同步機制

a.ThreadLocal與同步機制都是為了解決多線程中相同變量的訪問沖突問題

b.前者采用以”空間換時間”的方法,后者采用以”時間換空間”的方式

現(xiàn)在都明白了吧碍扔。各有優(yōu)劣瘩燥,各有適用場景。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末不同,一起剝皮案震驚了整個濱河市厉膀,隨后出現(xiàn)的幾起案子溶耘,更是在濱河造成了極大的恐慌,老刑警劉巖服鹅,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凳兵,死亡現(xiàn)場離奇詭異,居然都是意外死亡企软,警方通過查閱死者的電腦和手機庐扫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仗哨,“玉大人形庭,你說我怎么就攤上這事≡逯危” “怎么了碘勉?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桩卵。 經(jīng)常有香客問我验靡,道長,這世上最難降的妖魔是什么雏节? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任胜嗓,我火速辦了婚禮,結(jié)果婚禮上钩乍,老公的妹妹穿的比我還像新娘辞州。我一直安慰自己,他們只是感情好寥粹,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布变过。 她就那樣靜靜地躺著,像睡著了一般涝涤。 火紅的嫁衣襯著肌膚如雪媚狰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天阔拳,我揣著相機與錄音崭孤,去河邊找鬼。 笑死糊肠,一個胖子當著我的面吹牛辨宠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播货裹,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼嗤形,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弧圆?” 一聲冷哼從身側(cè)響起派殷,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤还最,失蹤者是張志新(化名)和其女友劉穎墓阀,沒想到半個月后毡惜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡斯撮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年经伙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片勿锅。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡帕膜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出溢十,到底是詐尸還是另有隱情垮刹,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布张弛,位于F島的核電站荒典,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吞鸭。R本人自食惡果不足惜寺董,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刻剥。 院中可真熱鬧遮咖,春花似錦、人聲如沸造虏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漓藕。三九已至陶珠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撵术,已是汗流浹背背率。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嫩与,地道東北人寝姿。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像划滋,于是被迫代替她去往敵國和親饵筑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

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

  • Java-Review-Note——4.多線程 標簽: JavaStudy PS:本來是分開三篇的处坪,后來想想還是整...
    coder_pig閱讀 1,629評論 2 17
  • 從三月份找實習到現(xiàn)在根资,面了一些公司架专,掛了不少,但最終還是拿到小米玄帕、百度部脚、阿里、京東裤纹、新浪委刘、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,192評論 11 349
  • 轉(zhuǎn)載:http://blog.csdn.net/wenwen091100304/article/details/4...
    Jannonx閱讀 217評論 0 0
  • 散落一地的楓葉鹰椒,是誰的思念 這個夜锡移,安靜得聽不到心跳的聲音 這個夜,思念的你漆际,還好嗎 這個夜淆珊,那一句“我想你”還縈...
    321小肥仔閱讀 189評論 0 0
  • //接口定義 [修飾符] interface 接口名 [extends 父接口列表]{ [public stati...
    守護之物閱讀 136評論 0 0