Android 多線程之synchronized鎖住的是代碼還是對象(二)

Android 線程簡單分析(一)
Android 并發(fā)之synchronized鎖住的是代碼還是對象(二)
Android 并發(fā)之CountDownLatch垃帅、CyclicBarrier的簡單應(yīng)用(三)
Android 并發(fā)HashMap和ConcurrentHashMap的簡單應(yīng)用(四)(待發(fā)布)
Android 并發(fā)之Lock、ReadWriteLock和Condition的簡單應(yīng)用(五)
Android 并發(fā)之CAS(原子操作)簡單介紹(六)
Android 并發(fā)Kotlin協(xié)程的重要性(七)(待發(fā)布)
Android 并發(fā)之AsyncTask原理分析(八)(待發(fā)布)
Android 并發(fā)之Handler脱吱、Looper羡宙、MessageQueue和ThreadLocal消息機(jī)制原理分析(九)
Android 并發(fā)之HandlerThread和IntentService原理分析(十)

在java中多線程并發(fā)時,多個線程同時請求一個共享資源,必然會導(dǎo)致此資源的數(shù)據(jù)不安全抱完,可能我們就需要synchronized同步避免線程并發(fā)訪問共享資源導(dǎo)致數(shù)據(jù)不安全,但是synchronized鎖住的是代碼還是對象刃泡?

看一下栗子:

public class SynchronizedExample {

 public synchronized void share() {
    Log.e("tag", "share 開始執(zhí)行.....");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    Log.e("tag", "share 結(jié)束.....");
    }
}

  class SynchronizedExampleThread extends Thread {
    @Override
    public void run() {
        SynchronizedExample example = new SynchronizedExample();
        example.share();
    }
}

1巧娱、在SynchronizedExample 的share方法加synchronized 打印結(jié)果:

share 開始執(zhí)行.....
share 開始執(zhí)行.....
share 開始執(zhí)行.....
share 結(jié)束.....
share 結(jié)束.....
share 結(jié)束.....

可以看出來,上面的起動了三個線程烘贴,同時運行SynchronizedExample 類中的share方法禁添,雖然share方法加上了synchronized,但是還是同時運行起來桨踪,好像synchronized并沒起到同步的這用作用老翘?

再來改改,改成同步代碼塊锻离?

 public void share() {
    synchronized (this) {
        Log.e("tag", "share 開始執(zhí)行.....");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Log.e("tag", "share 結(jié)束.....");
    }
} 

結(jié)果還是和上面的一樣

share 開始執(zhí)行.....
share 開始執(zhí)行.....
share 開始執(zhí)行.....
share 結(jié)束.....
share 結(jié)束.....
share 結(jié)束.....

在java中铺峭,synchronized(this)以及非static的synchronized方法,只能防止多個線程同時執(zhí)行同一個對象的同步代碼段汽纠,即同一個鎖監(jiān)視器卫键。
分析一下上面的代碼?

實際上虱朵,在java中莉炉,對于非static的synchronized方法或者是synchronized代碼塊钓账,鎖的就是對象本身也就是this。是不是有答案了呢袱?

synchronized鎖住的是括號里的對象官扣,而不是代碼。

當(dāng)synchronized鎖住一個對象后羞福,別的線程如果也想拿到這個對象的鎖惕蹄,就必須等待(同步隊列)這個線程執(zhí)行完成釋放鎖,才能再次給對象加鎖治专,這樣才達(dá)到線程同步的目的卖陵,如果不明白可以看Android 線程簡單分析(一)介紹,很詳細(xì)张峰。

所以我們在用synchronized關(guān)鍵字的時候泪蔫,能縮小代碼段的范圍就盡量縮小,能在代碼段上加同步就不要再整個方法上加同步喘批。這叫減小鎖的粒度撩荣,使代碼更大程度的并發(fā)。鎖的代碼段太長了饶深,別的線程是不是要等很久餐曹。

再看上面的代碼,每個線程中都new了一個SynchronizedExample 類的對象敌厘,也就是產(chǎn)生了三個SynchronizedExample 對象台猴,由于不是同一個對象,所以可以多線程同時運行synchronized方法或代碼段俱两。

驗證:

 SynchronizedExample example = new SynchronizedExample();
class SynchronizedExampleThread extends Thread {
    @Override
    public void run() {
        example.share();
    }
}

結(jié)果:

 share 開始執(zhí)行.....
 share 結(jié)束.....
 share 開始執(zhí)行.....
 share 結(jié)束.....
 share 開始執(zhí)行.....
 share 結(jié)束.....

synchronized就起了作用饱狂。

為了在明確一點我在創(chuàng)建兩個SynchronizedExample 對象:

  SynchronizedExample example = new SynchronizedExample();
  SynchronizedExample example2 = new SynchronizedExample();

class SynchronizedExampleThread extends Thread {
    @Override
    public void run() {
        example.share();
    }
}

class SynchronizedExampleThread2 extends Thread {
    @Override
    public void run() {
        example2.share2();
    }
}

結(jié)果:

share 開始執(zhí)行.....
share2 開始執(zhí)行.....
share 結(jié)束.....
share 開始執(zhí)行.....
share2 結(jié)束.....
share2 開始執(zhí)行.....
share 結(jié)束.....
share 開始執(zhí)行.....
share2 結(jié)束.....
share2 開始執(zhí)行.....
share 結(jié)束.....
share2 結(jié)束.....

明顯同一個所得是同一個對象,即同一把鎖宪彩。

未命名文件.png
  • 同一個對象每條線程進(jìn)入同步代碼塊休讳,其他線程將進(jìn)入同步隊列或鎖池中等待其他線程釋放鎖,synchronize屬于非公平鎖毯焕,在鎖池的等待的線程在線程1釋放鎖開始競爭鎖衍腥,所以synchronize鎖的是對象。

  • 非公平鎖和公平鎖
    1纳猫、非公平鎖:線程加鎖時直接嘗試獲取鎖婆咸,獲取不到就自動到隊尾等待,ReentrantLock(默認(rèn))和synchronize屬于非公平鎖芜辕。
    2尚骄、公平鎖:加鎖前先查看是否有排隊等待的線程,有的話優(yōu)先處理排在前面的線程侵续,先來先得倔丈。

  • 樂觀鎖和悲觀鎖
    1憨闰、悲觀鎖:假設(shè)一定會發(fā)生并發(fā)沖突,通過阻塞其他所有線程來保證數(shù)據(jù)的完整性需五,就是屬于悲觀主義鹉动,synchronize就是悲觀鎖。
    2宏邮、樂觀鎖:假設(shè)不會發(fā)生并發(fā)沖突泽示,直接不加鎖去完成某項更新,如果沖突就返回失敗蜜氨,CAS機(jī)制屬于樂觀的械筛。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市飒炎,隨后出現(xiàn)的幾起案子埋哟,更是在濱河造成了極大的恐慌,老刑警劉巖郎汪,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赤赊,死亡現(xiàn)場離奇詭異,居然都是意外死亡煞赢,警方通過查閱死者的電腦和手機(jī)砍鸠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耕驰,“玉大人,你說我怎么就攤上這事录豺‰猓” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵双饥,是天一觀的道長媒抠。 經(jīng)常有香客問我,道長咏花,這世上最難降的妖魔是什么趴生? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮昏翰,結(jié)果婚禮上苍匆,老公的妹妹穿的比我還像新娘。我一直安慰自己棚菊,他們只是感情好浸踩,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著统求,像睡著了一般检碗。 火紅的嫁衣襯著肌膚如雪据块。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天折剃,我揣著相機(jī)與錄音另假,去河邊找鬼。 笑死怕犁,一個胖子當(dāng)著我的面吹牛边篮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播因苹,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼苟耻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了扶檐?” 一聲冷哼從身側(cè)響起凶杖,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎款筑,沒想到半個月后智蝠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡奈梳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年杈湾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攘须。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡漆撞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出于宙,到底是詐尸還是另有隱情浮驳,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布捞魁,位于F島的核電站至会,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏谱俭。R本人自食惡果不足惜奉件,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望昆著。 院中可真熱鬧县貌,春花似錦、人聲如沸凑懂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杭攻,卻和暖如春祟敛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兆解。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工馆铁, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锅睛。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓埠巨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親现拒。 傳聞我的和親對象是個殘疾皇子辣垒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

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

  • 1、Synchronized關(guān)鍵字 1印蔬、方法中的變量不存在非線程安全問題勋桶,都是線程安全的。 2侥猬、兩個線程訪問同一個...
    AI喬治閱讀 1,198評論 1 7
  • 本文出自 Eddy Wiki 例驹,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,116評論 0 14
  • 進(jìn)程和線程 進(jìn)程 所有運行中的任務(wù)通常對應(yīng)一個進(jìn)程,當(dāng)一個程序進(jìn)入內(nèi)存運行時,即變成一個進(jìn)程.進(jìn)程是處于運行過程中...
    勝浩_ae28閱讀 5,106評論 0 23
  • ??一個任務(wù)通常就是一個程序,每個運行中的程序就是一個進(jìn)程退唠。當(dāng)一個程序運行時鹃锈,內(nèi)部可能包含了多個順序執(zhí)行流,每個順...
    OmaiMoon閱讀 1,671評論 0 12
  • 前言 本篇主要介紹Java多線程中的同步瞧预,也就是如何在Java語言中寫出線程安全的程序屎债,如何在Java語言中解決非...
    嘟爺MD閱讀 1,851評論 5 28