再深入聊聊 synchronized 關鍵字,面試必備知識

當synchronized關鍵字,有不少同學已經耳熟能詳了,作為作為複習還是要鞏固一下,因為面試常問這個東西。


第一個是多個線程去訪問同一個資源的時候,對這個資源要上鎖。為什麼要上鎖呢?訪問某一段代碼或者某臨界資源的時候是需要有一把鎖的概念的。


比如:我們對一個數字做遞增,兩個程序對它一塊兒來做遞增,遞增就是把一個程序往上加1,如果兩個線程共同訪問的時候,第一個線程讀它是0,然後把它加1,在自己線程內部內存裡面算還沒有寫回去的時候,第二個線程讀到了它還是0,加1再寫回去,本來加了兩次,但是還是1。


那麼我們在對這個數字遞增的過程中上把鎖,就是說第一個線程對這個數字訪問的時候是獨佔的,不允許別的線程來訪問,不允許別的線程來對它進行計算,我必須加完1再釋放鎖,其他線程才能對它繼續加。


實質上,這把鎖並不是對數字進行鎖定的,你可以任意指定,想鎖誰就鎖誰。


我第一個程序是這麼寫的,如果說你想上了把鎖之後才能對count進行減減訪問,你可以new一個Object,所以這裡鎖定就是0,當我拿到這把鎖的時候才能執行這段代碼。


<code>/**
 * synchronized關鍵字
 * 對某個對象加鎖
 * @author mashibing
 */package com.mashibing.juc.c_001;public class T {    private int count = 10;  private Object o = new Object();    public void m() {    synchronized(o) { //任何線程要執行下面的代碼,必須先拿到o的鎖      count--;      System.out.println(Thread.currentThread().getName() + " count = " + count);    }  }  }/<code>


我們來談一下synchronized的一些特性。如果說你每次都定義一個鎖的對象Object o,把它new出來,那加鎖的時候太麻煩,每次都要new一個新的對象出來。所以呢,最簡單的方式就是synchronized(this),鎖定當前對象就行。


<code>/**
 * synchronized關鍵字
 * 對某個對象加鎖
 * @author mashibing
 */package com.mashibing.juc.c_002;public class T {    private int count = 10;    public void m() {    synchronized(this) { //任何線程要執行下面的代碼,必須先拿到this的鎖      count--;      System.out.println(Thread.currentThread().getName() + " count = " + count);    }  }  }/<code>


如果你要是鎖定當前對象,你也可以寫成synchronized方法,這個和synchronized(this)是等值的。


<code>/**
 * synchronized關鍵字
 * 對某個對象加鎖
 * @author mashibing
 */package com.mashibing.juc.c_003;public class T {  private int count = 10;    public synchronized void m() { //等同於在方法的代碼執行時要synchronized(this)    count--;    System.out.println(Thread.currentThread().getName() + " count = " + count);  }}/<code>


我明知道靜態方法static是沒有this對象的,你不需要new出一個對象來就能執行這個方法,但是如果這個上面加一個synchronized的話就表示synchronized(T.class),這裡這個synchronized(T.class)鎖的就是T類的對象。


<code>/**
 * synchronized關鍵字
 * 對某個對象加鎖
 * @author mashibing
 */package com.mashibing.juc.c_004;public class T {  private static int count = 10;    public synchronized static void m() { //這裡等同於synchronized(FineCoarseLock.class)    count--;    System.out.println(Thread.currentThread().getName() + " count = " + count);  }    public static void mm() {    synchronized(T.class) { //考慮一下這裡寫synchronized(this)是否可以?      count --;    }  }}/<code>


推薦學習資源

再深入聊聊 synchronized 關鍵字,面試必備知識


分享到:


相關文章: