Question

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

Était-ce utile?

La solution

Vous pouvez uniquement savoir si le thread actuel détient un verrou normal (Thread.holdsLock(Object)).Vous ne pouvez pas obtenir de référence au thread qui possède le verrou sans code natif.

Cependant, si vous faites quelque chose de compliqué avec le threading, vous souhaiterez probablement vous familiariser avec les packages java.util.concurrent.Le ReentrantLock vous permet d'obtenir son propriétaire (mais c'est une méthode protégée, vous devrez donc l'étendre).En fonction de votre application, il se peut qu'en utilisant les packages de concurrence, vous constatiez que vous n'avez finalement pas besoin d'obtenir le propriétaire du verrou.

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

Autres conseils

Vous pouvez accéder aux mèches retenues 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 sur lesquels vous pouvez utiliser le IdentityHashCode pour comparer au verrou en question.

Vous pouvez, à partir de la version 1.6, utiliser JMX pour faire toutes sortes de choses intéressantes, notamment rechercher des verrous détenus.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).

Il y a un exemple dans l'un de mes blogs.

Courir jconsole.Il est inclus dans le SDK Java et s'exécute à partir de la ligne de commande.Je ne suis pas sûr du système d'exploitation que vous utilisez, mais sous Windows, vous pouvez simplement lui transmettre le PID du processus Java.Cela devrait vous aider à trouver le fil à l'origine du problème.Vous pouvez également utiliser un profileur commercial comme YourKit ou un certain nombre d'autres profileurs.

Dans la version 1.5, vous pouvez trouver tous les threads et obtenir l'état de chacun, par exemple comme ceci :

    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 indique si le fil est BLOQUÉ, EN ATTENTE, etc., voir État de fil de l'API jdk

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

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

Si c'est serrure rentrante vous pouvez vérifier s'il est détenu par le fil de discussion actuel

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

Vous pouvez utiliser une variable pour conserver le thread actuel 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;
    }
}

Moche mais ça marche.

String findLockOwner(ReentrantLock lock) {
    String patternStr = "\\[Locked by thread (\\S+)\\]";
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher = pattern.matcher(lock.toString());
    boolean matchFound = matcher.find();
    if (matchFound && matcher.groupCount() >= 1) {
      return matcher.group(1);
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top