理解java中的synchronized關鍵字

目標:

理解synchronized含義、明確synchronized關鍵字修飾普通方法、靜態方法、和代碼塊時鎖對象的差異
有如下一個類A

class A {
    public synchronized void a() {
    }

    public synchronized void b() {
    }
}

然後創建兩個對象

A a1 = new A();
A a2 = new A();

然後在兩個線程中併發訪問如下代碼:

Thread1                       Thread2
a1.a();                       a2.a();

請問二者能否構成線程同步?
如果A的定義是下面這種呢?

class A {
    public static synchronized void a() {
    }

    public static synchronized void b() {
    }
}

答案:

第一種不會同步,鎖的是A的實例對象(this),a1,a2是兩個不同的實例,不同線程的不同對象訪問不會同步;第二種可以同步,修飾靜態方法,鎖的是類對象(this.class),a1和a2的同步鎖一樣,所以可以同步。

分析:

Synchronized是java中的關鍵字,是一種同步鎖,用來實現多線程的同步機制,保證同一時間只有一個線程可以操作對應資源。可以修飾方法、代碼塊


Synchronized的機制:
Synchronized在實現同步的時候會聲明一把鎖,表明必須持有這把鎖的線程才能訪問執行,在一個線程需要執行這塊代碼時,會先嚐試持有這把指定的鎖,如果這個鎖已經被別的線程持有,那麼該線程就會開始等待,知道這把鎖被釋放後纔會繼續執行,並且在執行時會一直持有這把鎖,以防止其他線程進入這把鎖控制的代碼,直到該線程執行完纔會釋放鎖


Synchronized修飾對象有三種:

  1. 修飾普通方法 此時加鎖的方法只允許一個線程訪問,但是這種情況下鎖的是該方法的實例對象(即題中Anew出來的對象),如果多個線程不同的對象訪問該方法,則無法保證同步。
  2. 修飾靜態方法 靜態方法是類方法,所以此時鎖的是包含這個方法的類(即A.class),也就是類對象,這種情況下,多個線程不同對象訪問該靜態方法,也是可以保證同步的
  3. 修飾代碼塊 修飾普通代碼塊同步效果跟修飾普通方法一樣,修飾靜態代碼塊同步效果和修飾靜態方法類似

參考星球夥伴回答

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章