多线程 - Java synchronized(t)的问题,如何知道某个对象t,是否被这样锁住了呢?
PHPz
PHPz 2017-04-17 17:53:17
0
1
322

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

PHPz
PHPz

学习是最好的投资!

全部回覆(1)
小葫芦

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()

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板