2008-09-08 86 views
37

是否有可能在運行時以編程方式檢查持有給定對象的鎖的線程的名稱?以編程方式確定哪個Java線程持有鎖

+1

請修改您的標題和發佈,以表明你的意思是Java可以可以檢查。標籤不應該是與問題有關的唯一重要信息。 – 2008-09-08 20:24:52

回答

22

您只能分辨當前線程是否保持正常鎖定(Thread.holdsLock(Object))。無法獲得對沒有本機代碼的鎖定的線程的引用。然而,如果你正在做任何與線程複雜的事情,你可能想要熟悉java.util.concurrent包。 ReentrantLock確實可以讓你獲得它的所有者(但它是一種受保護的方法,所以你必須擴展它)。根據你的應用程序,很可能通過使用併發包,你會發現你根本不需要獲得鎖的所有者。

有非編程方法來查找鎖擁有者,例如發信號通知JVM向stderr發出線程轉儲,這對確定死鎖的原因很有用。

4

運行jconsole。它包含在Java SDK中,並從命令行運行。我不確定你使用的是什麼操作系統,但是在windows上,你可以將它傳遞給java進程的PID。它應該可以幫助您找到導致問題的線程。或者,您可以使用像YourKit這樣的商業分析器或任何數量的其他分析器。

7

從1.6開始,您可以使用JMX來執行各種有趣的事情,包括查找持有的鎖。你不能得到實際的對象,但你得到的類和身份哈希值(這是不唯一的)。

There's an example in one of my weblogs.

3

在1.5,你可以找到所有的線程,並得到每個人的狀態,例如像這樣:

Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces(); 
    for (Map.Entry<Thread, StackTraceElement[]> threadEntry : map.entrySet()) { 
     log.info("Thread:"+threadEntry.getKey().getName()+":"+threadEntry.getKey().getState()); 
     for (StackTraceElement element : threadEntry.getValue()) { 
      log.info("--> "+element); 
     } 
    } 

Thread.getState向您提供有關線程是否被阻塞,等待等,請參見jdk api ThreadState

12

您可以通過反射獲得線程保持的鎖定。這隻適用於java 1.6。

ThreadMXBean bean = ManagementFactory.getThreadMXBean(); 
ThreadInfo[] ti = bean.getThreadInfo(bean.getAllThreadIds(), true, true); 

有關每個ThreadInfo對象有哪些,你可以使用identityHashCode對他們比較有問題的鎖LockInfo對象。

0

你可以使用一個變量來保存當前線程,當你鎖定時,然後打印它,如果別人正在嘗試使用它。

Thread holderOfLock = null; 
Object theLock = new Object(); 

public void doStuff() 
{ 
    if(holderOfLock != null) 
    { 
     //get and print name of holderOfLock-thread or get stacktrace etc. 
    } 

    synchronized (theLock) 
    { 
     holderOfLock = Thread.currentThread(); 
     //do stuff... 
     holderOfLock = null; 
    } 
} 
1

你可以通過調用wait()或對象notify()方法檢查特定對象的鎖。如果物體沒有鎖定,那麼它會拋出llegalMonitorStateException

2-通過調用holdsLock(Object o)方法。這將返回布爾值。

1

如果是重新-entrant鎖ü如果它是由當前線程保持

final ReentrantLock lock = new ReentrantLock(); 
lock.isHeldByCurrentThread();