試官最喜歡問的Synchronized的5種用法,你知道幾個?

前言

咱們都知道 Synchronized 是線程安全同步用的,大部分程序可能只會用到同步方法上面。其實 Synchronized 能夠用到更多的場合,列舉了如下幾個用法。

一、同步普通方法

這個也是咱們用得最多的,只要涉及線程安全,上來就給方法來個同步鎖。這種方法使用雖然最簡單,可是隻能做用在單例上面,若是不是單例,同步方法鎖將失效。
/**
 * 用在普通方法
 */
private synchronized void synchronizedMethod() {
    System.out.println("synchronizedMethod");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


複製代碼
此時,同一個實例只有一個線程能獲取鎖進入這個方法。

二、同步靜態方法

同步靜態方法,無論你有多少個類實例,同時只有一個線程能獲取鎖進入這個方法。
/**
 * 用在靜態方法
 */
private synchronized static void synchronizedStaticMethod() {
    System.out.println("synchronizedStaticMethod");
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


複製代碼
同步靜態方法是類級別的鎖,一旦任何一個線程進入這個方法,其餘全部線程將沒法訪問這個類的任何同步類鎖的方法。

三、同步類

下面提供了兩種同步類的方法,鎖住效果和同步靜態方法同樣,都是類級別的鎖,同時只有一個線程能訪問帶有同步類鎖的方法。
/**
 * 用在類
 */
private void synchronizedClass() {
    synchronized (TestSynchronized.class) {
        System.out.println("synchronizedClass");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * 用在類
 */
private void synchronizedGetClass() {
    synchronized (this.getClass()) {
        System.out.println("synchronizedGetClass");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


複製代碼
這裏的兩種用法是同步塊的用法,這裏表示只有獲取到這個類鎖才能進入這個代碼塊。

四、同步this實例

這也是同步塊的用法,表示鎖住整個當前對象實例,只有獲取到這個實例的鎖才能進入這個方法。
/**
 * 用在this
 */
private void synchronizedThis() {
    synchronized (this) {
        System.out.println("synchronizedThis");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


複製代碼
用法和同步普通方法鎖同樣,都是鎖住整個當前實例。

五、同步對象實例

這也是同步塊的用法,和上面的鎖住當前實例同樣,這裏表示鎖住整個 LOCK 對象實例,只有獲取到這個 LOCK 實例的鎖才能進入這個方法。
/**
 * 用在對象
 */
private void synchronizedInstance() {
    synchronized (LOCK) {
        System.out.println("synchronizedInstance");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


複製代碼
另外,類鎖與實例鎖不相互阻塞,但相同的類鎖,相同的當前實例鎖,相同的對象鎖會相互阻塞。

最後 

歡迎你們關注個人公衆號【程序員追風】,文章都會在裏面更新,整理的資料也會放在裏面。程序員

相關文章
相關標籤/搜索