Java synchronized關鍵字

使用 Synchronized 關鍵字來解決并發(fā)問題是最簡單的一種方式凫碌,我們只需要使用它修飾需要被并發(fā)處理的代碼塊扑毡、方法或字段屬性,虛擬機自動為它加鎖和釋放鎖盛险,并將不能獲得鎖的線程阻塞在相應的阻塞隊列上瞄摊。
下面通過幾個例子看下Synchronized 的用法
1、不加鎖控制

public class TestSynchronized {
    
    public void print1() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }
    
    public void print2() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }

    private void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    

    public static void main(String[] args) {
        
        TestSynchronized obj = new TestSynchronized();
        
        Thread threadA = new Thread(new Runnable() {            
            @Override
            public void run() {
                obj.print1();
            }
        });
        
        Thread threadB = new Thread(new Runnable() {            
            @Override
            public void run() {
                obj.print2();
            }
        });
        
        threadA.start();
        threadB.start();
        
    }

}

上述代碼沒有通過Synchronized 控制苦掘,print1和print2方法分別在不同的線程中執(zhí)行换帜,可以想象結果應該是交叉輸出的

Thread-1 : 4
Thread-0 : 4
Thread-1 : 3
Thread-0 : 3
Thread-0 : 2
Thread-1 : 2
Thread-0 : 1
Thread-1 : 1
Thread-0 : 0
Thread-1 : 0

2、使用Synchronized

    public synchronized void print1() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }
    
    public synchronized void print2() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }

可以看出結果是依次打印的

Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0
Thread-1 : 4
Thread-1 : 3
Thread-1 : 2
Thread-1 : 1
Thread-1 : 0

print1()和print2()前面的Synchronized獲取的是同一個鎖鹤啡,都是當前對象實例的內置鎖惯驼,所以當有一個線程獲取了這個鎖之后,其他需要調用帶Synchronized方法的線程只能阻塞递瑰。
3祟牲、Synchronized修飾代碼塊

    public void print1() {
        synchronized (this) {       
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                sleep(500);
            }
        }
    }
    
    public synchronized void print2() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }

結果一樣是依次輸出

Thread-1 : 4
Thread-1 : 3
Thread-1 : 2
Thread-1 : 1
Thread-1 : 0
Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0

代碼塊前的synchronized 和print2()前的synchronized獲取的都是同一個對象的內置鎖。
4抖部、引入static

    public void print1() {
        synchronized (this) {       
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                sleep(500);
            }
        }
    }
    
    public static synchronized void print2() {
        int i = 5;
        while (i-- > 0) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            sleep(500);
        }
    }

結果又變成交叉的了

Thread-1 : 4
Thread-0 : 4
Thread-1 : 3
Thread-0 : 3
Thread-1 : 2
Thread-0 : 2
Thread-0 : 1
Thread-1 : 1
Thread-0 : 0
Thread-1 : 0

代碼塊前的synchronized獲取的是當前對象的內置鎖说贝, print2是static獲取的是類對象的內置鎖,兩個鎖之前不存在競爭關系慎颗,同一個線程可以同時擁有兩把鎖乡恕。

原理解析

synchronized的使用需要借助java的內置鎖言询,首先看下內置鎖是什么
java的內置鎖:每個java對象都可以用做一個實現(xiàn)同步的鎖,這些鎖稱為內置鎖几颜。線程進入同步代碼塊或方法的時候會自動獲得該鎖倍试,在退出同步代碼塊或方法時會釋放該鎖。獲得內置鎖的唯一途徑就是進入這個鎖的保護的同步代碼塊或方法蛋哭。
示例2和3都是依次輸出的县习,說明兩個線程獲取的都是同一個對象鎖。
示例4 synchronized同時修飾靜態(tài)方法和實例方法谆趾,但是運行結果是交替進行的躁愿,這證明了類鎖和對象鎖是兩個不一樣的鎖,控制著不同的區(qū)域沪蓬,它們是互不干擾的彤钟。同樣,線程獲得對象鎖的同時跷叉,也可以獲得該類鎖逸雹,即同時獲得兩個鎖,這是允許的云挟。
引自:
https://www.cnblogs.com/edwardru/articles/6030686.html

synchronized是可重入的
引自:
https://blog.csdn.net/u012545728/article/details/80843595

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末梆砸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子园欣,更是在濱河造成了極大的恐慌帖世,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沸枯,死亡現(xiàn)場離奇詭異日矫,居然都是意外死亡,警方通過查閱死者的電腦和手機绑榴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門哪轿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人翔怎,你說我怎么就攤上這事缔逛。” “怎么了姓惑?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵褐奴,是天一觀的道長。 經(jīng)常有香客問我于毙,道長敦冬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任唯沮,我火速辦了婚禮脖旱,結果婚禮上堪遂,老公的妹妹穿的比我還像新娘。我一直安慰自己萌庆,他們只是感情好溶褪,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著践险,像睡著了一般猿妈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巍虫,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天彭则,我揣著相機與錄音,去河邊找鬼占遥。 笑死俯抖,一個胖子當著我的面吹牛,可吹牛的內容都是我干的瓦胎。 我是一名探鬼主播芬萍,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搔啊!你這毒婦竟也來了担忧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤坯癣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后最欠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體示罗,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年芝硬,在試婚紗的時候發(fā)現(xiàn)自己被綠了蚜点。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡拌阴,死狀恐怖绍绘,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情迟赃,我是刑警寧澤陪拘,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站纤壁,受9級特大地震影響左刽,放射性物質發(fā)生泄漏。R本人自食惡果不足惜酌媒,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一欠痴、第九天 我趴在偏房一處隱蔽的房頂上張望迄靠。 院中可真熱鬧,春花似錦喇辽、人聲如沸掌挚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吠式。三九已至,卻和暖如春旦委,著一層夾襖步出監(jiān)牢的瞬間奇徒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工缨硝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留摩钙,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓查辩,卻偏偏與公主長得像胖笛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宜岛,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內容

  • 前言 本人主要是結合《Java多線程編程核心技術》這本書的第二章內容长踊,對synchronized關鍵字的知識進行梳...
    AR7_閱讀 894評論 0 4
  • 1. synchronized原理 ??在單線程中不會出現(xiàn)線程安全問題,而在多線程編程中萍倡,有可能會出現(xiàn)同時訪問同一...
    Skymiles閱讀 234評論 2 0
  • 本文是我自己在秋招復習時的讀書筆記身弊,整理的知識點,也是為了防止忘記列敲,尊重勞動成果阱佛,轉載注明出處哦!如果你也喜歡戴而,那...
    波波波先森閱讀 11,257評論 4 56
  • 2017年8月19日00:13 夜太靜凑术,有些孤單 還有些許難過 日子有些難挨 再難也要走下去,對不對 最終還是要一個人走
    e7f4cec93b9b閱讀 150評論 0 0
  • 3月25日凌晨四點就起床了所意,因為今天我們一班跑友會一齊踏上去海南三亞參加馬拉松比賽淮逊;心里亂呀、一夜都沒睡好扶踊、畢竟第...
    山之峰1閱讀 169評論 0 0