首頁  >  問答  >  主體

java - 一个类的对象锁只有一个,类锁呢?

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

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

高洛峰高洛峰2744 天前697

全部回覆(6)我來回復

  • 巴扎黑

    巴扎黑2017-04-18 10:51:00

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

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 10:51:00

    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物件當鎖,因為一般情況下一個類別的類別實例只有一個,那麼每次進入這個方法都會鎖。稱為類級鎖。

    回覆
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:51:00

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

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

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

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-18 10:51:00

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

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:00

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

    【非靜態方法】

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

    【靜態方法】

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

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

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

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

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

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:00

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

    回覆
    0
  • 取消回覆