2009-07-28 105 views
1

讓我們假設一個線程在Java中的同步函數中執行,而另一個線程想要訪問相同的方法,但它必須等到第一個線程完成。 第二個線程如何知道哪個線程在對象上具有鎖定。 我想打印第一個線程的細節,可能從第一個線程的啓動位置開始。如何獲取線程鎖定對象的詳細信息

回答

2

如果您使用的是java.util.concurrent.locks.ReentrantLock,那麼子類可以調用getOwner

或者,您可以使用JMX。迭代通過線程找到適當的getLockedMonitors()getLockedSynchronizers()java.lang.management.ThreadInfo

0

我相信這是不可能的。但是你可以做一些額外的編碼類似的事情:

public void myFunction() { 
    System.out.println("" + Thread.currentThread() + " entering sync @ myFunction"); 
    synchronized(this) { 
    System.out.println("" + Thread.currentThread() + " entered sync @ myFunction"); 

    ... 

    System.out.println("" + Thread.currentThread() + " leaving sync @ myFunction"); 
    } 
    System.out.println("" + Thread.currentThread() + " left sync @ myFunction"); 
} 
2

這是一個有點棘手,幾乎什麼湯姆Hawtin寫的,但在dumpAllThreads得到一個ThreadInfo當你必須顯式地請求監控信息。 喜歡的東西:

Object lock = ... 
    ThreadMXBean mx = ManagementFactory.getThreadMXBean(); 
    ThreadInfo[] allInfo = mx.dumpAllThreads(true, false); 
    for (ThreadInfo threadInfo : allInfo) { 
     MonitorInfo[] monitors = threadInfo.getLockedMonitors(); 
     for (MonitorInfo monitorInfo : monitors) { 
      if (monitorInfo.getIdentityHashCode() == System.identityHashCode(lock)) { 
       StackTraceElement[] stackTrace = threadInfo.getStackTrace(); 
       // use the the Information from threadInfo 
      } 
     } 
    } 
1

這是用於診斷目的,或者是您要爲您的應用程序的一部分使用的功能。如果它是用於診斷的,那麼其他答案中的各種詳細日誌記錄解決方案可能足以讓你走。如果您想將其作爲功能的一部分來實現,那麼您確實應該使用比​​關鍵字更強大和更靈活的功能,例如@Tom提到的ReentrantLock wizardry。