java - 一个类的对象锁只有一个,类锁呢?
高洛峰
高洛峰 2017-04-18 10:49:00
0
6
693

一个类的对象锁只有一个,如果有几个非静态函数都是synchronized,在某一时刻只有一个线程能调用其中一个函数

假如一个类有几个静态函数是synchronized,在某一时刻只有一个线程能调用其中一个静态函数吗?也就是类锁也只有一个吗?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回覆(6)
巴扎黑

前面一種鎖的是實例對象,鎖定了當前的那個對象,如果有多個實例對象,這些synchronized方法之間不是同步的。第二種鎖的是類別對象,類別對象就一個,所以是同步的。

洪涛
public class Foo {

    synchronized void test1() {
        //to implements
    }

    void test2() {
        synchronized(this) {
            //to implements
        }
    }

    synchronized static void test3() {
        //to implements
    }

    static void test4() {
        synchronized(Foo.class) {
            //to implements
        }
    }
}

如上程式碼,test1方法相當於test2,當this是同一個物件時,就會發生阻塞。當然,不同對象沒有關係,因為this不一樣。稱為物件級鎖。
test3相當於test4,這裡是用class物件當鎖,因為一般情況下一個類別的類別實例只有一個,那麼每次進入這個方法都會鎖。稱為類級鎖。

大家讲道理
  • 非靜態同步方法(A)用的鎖就是當前實例物件本身,一個實例的A獲取鎖定之後,該實例的其他A必須等待鎖的釋放,多個實例用的都是不同的鎖;

  • 靜態同步方法(B)用的鎖是類別物件本身,一旦一個B取得鎖之後其他的B都必須等待釋放鎖,不管是一個實例還是多個實例;

另外 A和B之間用不同的鎖,所以不會有競爭關係;

左手右手慢动作

Class類別建立一個物件就是代表一個普通類,這時「類別鎖」就是這個實例物件上的鎖

伊谢尔伦

你說的是「互斥鎖」的概念,針對synchronized修飾法有兩種情況:

【非靜態方法】

當一個方法被synchronized修飾後,鎖定對象為目前方法所屬對象,即方法中的this。

【靜態方法】

當一個靜態方法被synchronized修飾後,此靜態方法上鎖的物件為目前類別物件(Class類別的實例)。每個類別都有唯一的一個類別物件。取得類別物件的方式:類別名稱.class。

而對於互斥的場景,需要理解兩點說明:

1、靜態方法與非靜態方法同時聲明了synchronized,他們之間是非互斥關係的。原因在於,靜態方法鎖的是類別物件而非靜態方法鎖的是目前方法所屬物件。

2、當Synchronized修飾的是兩段不同的程式碼,但是鎖定物件相同時,兩個執行緒分別呼叫者兩段程式碼時就是互斥的

所以你說的「一時刻只有一個執行緒能呼叫其中一個函數」(即互斥),判斷條件就是鎖物件是否相同,與方法型別無關。

伊谢尔伦

物件方法的synchronized修飾,鎖為物件自身,也就是this;
靜態方法的synchronized修飾,鎖為Class物件自身,也就是由類別載入器建立的類別物件;

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!