2008-09-08 5 views
37

Ist es zur Laufzeit möglich, den Namen des Threads programmgesteuert zu überprüfen, der die Sperre eines bestimmten Objekts enthält?Programmgesteuert bestimmen, welcher Java-Thread eine Sperre enthält

+1

Bitte Ihren Titel ändern und veröffentlichen, um anzuzeigen, dass Sie Java bedeuten. Ein Tag sollte nicht der einzige Ort sein, an dem kritische Informationen zu der Frage platziert werden. –

Antwort

22

Sie können nur feststellen, ob der aktuelle Thread eine normale Sperre enthält (Thread.holdsLock(Object)). Sie können keinen Verweis auf den Thread abrufen, der über die Sperre ohne systemeigenen Code verfügt.

Wenn Sie jedoch etwas mit Threading kompliziert machen, möchten Sie sich wahrscheinlich mit den Paketen java.util.concurrent vertraut machen. Die ReentrantLock erlaubt Ihnen, seinen Besitzer zu bekommen (aber es ist eine geschützte Methode, also müssten Sie diese erweitern). Abhängig von Ihrer Anwendung kann es durchaus sein, dass Sie bei Verwendung der Concurrency-Pakete feststellen, dass Sie den Besitzer der Sperre nicht benötigen.

Es gibt nicht programmatische Methoden zum Suchen der Sperrbesitzer, z. B. das Signalisieren, dass die JVM einen Thread-Dump an stderr ausgibt, um die Ursache von Deadlocks zu ermitteln.

4

Führen Sie jconsole. Es ist im Java SDK enthalten und wird über die Befehlszeile ausgeführt. Ich bin mir nicht sicher, welches Betriebssystem Sie verwenden, aber unter Windows können Sie einfach die PID des Java-Prozesses übergeben. Es sollte Ihnen helfen, den Thread zu finden, der das Problem verursacht. Oder Sie können einen kommerziellen Profiler wie YourKit oder eine beliebige Anzahl anderer Profiler verwenden.

7

Sie können ab 1.6 JMX verwenden, um alle möglichen interessanten Dinge zu erledigen, einschließlich der Suche nach gehaltenen Sperren. Sie können das tatsächliche Objekt nicht abrufen, aber Sie erhalten den Klassen- und Identitätshashwert (der nicht eindeutig ist).

There's an example in one of my weblogs.

3

In 1.5 können Sie alle Fäden finden und jedes Einzelnen Zustand erhalten, zum Beispiel wie folgt aus:

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 gibt Ihnen Informationen darüber, ob der Thread blockiert ist, WAITING usw. siehe jdk api ThreadState

12

Sie können an den Schlössern durch Gewinde mit Reflektion gehalten werden. Dies funktioniert nur mit Java 1.6.

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

Auf jedem dieser Thread dort LockInfo Objekte sind Objekte, die Sie identityHashCode auf sie verwenden können, um das Schloss in Frage zu vergleichen.

0

Sie können eine Variable verwenden, um den aktuellen Thread zu halten, wenn Sie die Sperre übernehmen, und ihn dann ausdrucken, wenn jemand anders versucht, ihn zu benutzen.

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

Sie die Sperre auf das jeweilige Objekt durch den Aufruf wait() oder notify() Methode für das Objekt überprüfen können. Wenn das Objekt die Sperre nicht hält, wird llegalMonitorStateException geworfen.

2- Durch Aufruf holdsLock(Object o) Methode. Dies wird den booleschen Wert zurückgeben.

1

wenn es re -entrant Sperre kann u kann prüfen, ob es nach aktuellem Thread gehalten wird

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