搜尋

首頁  >  問答  >  主體

多线程 - Java synchronized(t)的问题,如何知道某个对象t,是否被这样锁住了呢?

Java synchronized(t)这个关键字修饰的代码块,意思是说获得t的锁之后,才能运行代码块。那么问题来了,如何知道某个对象t,是否被这样锁住了呢?

PHPzPHPz2889 天前328

全部回覆(1)我來回復

  • 高洛峰

    高洛峰2017-04-17 17:55:17

    JDK裡的Object類別並沒有提供API來判斷一個物件的物件鎖是否被鎖住了。但以下的思路或許可行。

    一個物件在記憶體中的佈局包括以下幾個部分

    • 對象頭

    • 物件實例資料(這裡不關注)

    • 對齊的填充(這裡不關注)

    物件頭包含這個物件的一些元資料, 包括兩個部分:一個mark word字段,一個klass字段
    mark word中包含一個鎖標誌,當物件沒有被鎖住的時候,標誌位為0 ,否則為1。

    mark word的大小在不同的平台上大小也是不同的:

    For 32 bit JVM:
        _mark    : 4 byte constant
        _klass    : 4 byte pointer to class 
    
    For 64 bit JVM:
        _mark    : 8 byte constant
        _klass    : 8 byte pointer to class
    
    For 64 bit JVM with compressed-oops:
        _mark    : 8 byte constant
        _klass    : 4 byte pointer to class

    因此,只要能獲得markword,就能取得得到這個鎖標誌,那便能知道一個物件是否被鎖住了。可是JDK中,我們只能操作物件的實例資料(變數與方法),並沒有方法拿到物件的物件頭。因此可能需要用到Java裡的「黑科技」sun.misc.Unsafe

    以32位的jdk為例:

    Object obj = new Object();
    int markword = unsafe.getInt(obj, 0L);

    這裡的0L是偏移量。
    接著對markword進行位操作,markword裡面的具體內容樓主還要去搜一下才行。

    說回到樓主的問題上,也許樓主只是想要有一種方式知道鎖有沒有被持有,並不一定要跟對象t是否被synchronized鎖住了這樣的問題較勁。
    如果是的話,那樓主可以拋棄synchronized關鍵字,改用juc裡面的ReentrantLock吧,人家裡面有個方法可以判斷鎖是否被持有isLocked()

    回覆
    0
  • 取消回覆