2008-09-08 7 views
37

Est-il possible au moment de l'exécution de vérifier par programme le nom du thread qui contient le verrou d'un objet donné?Déterminer par programme quel thread Java contient un verrou

+1

S'il vous plaît modifier votre titre et afficher pour indiquer que vous voulez dire Java. Une étiquette ne doit pas être le seul endroit où des informations critiques relatives à la question sont placées. –

Répondre

22

Vous pouvez uniquement indiquer si le fil en cours contient un verrou normal (Thread.holdsLock(Object)). Vous ne pouvez pas obtenir une référence au thread qui a le verrou sans code natif. Cependant, si vous faites quelque chose de compliqué avec le thread, vous voudrez probablement vous familiariser avec les paquets java.util.concurrent. Le ReentrantLock vous permet d'obtenir son propriétaire (mais c'est une méthode protégée, donc vous devrez l'étendre). En fonction de votre application, il se peut que vous utilisiez les paquets de simultanéité pour constater que vous n'avez pas besoin d'obtenir le propriétaire du verrou après tout.

Il existe des méthodes non-programmatiques pour trouver les propriétaires de verrous, telles que la signalisation de la JVM pour émettre un vidage de thread vers stderr, qui sont utiles pour déterminer la cause des blocages.

4

Exécutez jconsole. Il est inclus dans Java SDK et est exécuté à partir de la ligne de commande. Je ne suis pas sûr quel système d'exploitation vous utilisez, mais sur les fenêtres, vous pouvez simplement passer le PID du processus Java. Cela devrait vous aider à trouver le fil qui cause le problème. Ou, vous pouvez utiliser un profileur commercial comme YourKit ou un certain nombre d'autres profileurs.

7

Vous pouvez, à partir de la version 1.6, utiliser JMX pour faire toutes sortes de choses intéressantes, y compris trouver des serrures bloquées. Vous ne pouvez pas obtenir l'objet réel, mais vous obtenez la valeur de hachage de classe et d'identité (qui n'est pas unique).

There's an example in one of my weblogs.

3

Dans la version 1.5, vous pouvez trouver tous les fils et obtenir l'état de chacun, par exemple, comme celui-ci:

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 vous donne des informations pour savoir si le fil est BLOQUE, WAITING etc , voir jdk api ThreadState

12

Vous pouvez obtenir les verrous maintenus par des fils avec réflexion. Cela ne fonctionne qu'avec Java 1.6.

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

Sur chacun de ces objets ThreadInfo il y a des objets LockInfo que vous pouvez utiliser le identityHashCode sur eux pour comparer à la serrure en question.

0

Vous pouvez utiliser une variable pour maintenir le thread en cours lorsque vous prenez le verrou, puis l'imprimer si quelqu'un d'autre essaie de l'utiliser.

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

Vous pouvez vérifier le verrou sur l'objet particulier en appelant wait() ou méthode notify() sur cet objet. Si l'objet ne tient pas le verrou, alors il lancera llegalMonitorStateException.

2- En appelant la méthode holdsLock(Object o). Cela retournera la valeur booléenne.

1

si elle est de lock -entrant u peut peut vérifier si elle est maintenue par thread courant

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