Программно определить, какой поток Java держит блокировку - PullRequest
40 голосов
/ 09 сентября 2008

Возможно ли во время выполнения программно проверить имя потока, который удерживает блокировку данного объекта?

Ответы [ 9 ]

25 голосов
/ 09 сентября 2008

Вы можете только сказать, содержит ли текущий поток нормальную блокировку (Thread.holdsLock(Object)). Вы не можете получить ссылку на поток с блокировкой без собственного кода.

Однако, если вы делаете что-то сложное с потоками, вы, вероятно, захотите ознакомиться с пакетами java.util.concurrent. ReentrantLock позволяет вам получить его владельца (но это защищенный метод, поэтому вам придется расширить его). В зависимости от вашего приложения, вполне возможно, что при использовании пакетов параллелизма вы обнаружите, что вам все равно не нужно получать владельца замка.

Существуют непрограммные методы поиска владельцев блокировок, например, сигнализация JVM о выдаче дампа потока в stderr, которые полезны для определения причины тупиков.

14 голосов
/ 04 сентября 2009

Вы можете попасть в замки, удерживаемые нитями с отражением. Это работает только с Java 1.6.

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

На каждом из этих объектов ThreadInfo есть объекты LockInfo, которые вы можете использовать для них identityHashCode для сравнения с рассматриваемой блокировкой.

7 голосов
/ 09 сентября 2008

С версии 1.6 вы можете использовать JMX для выполнения всевозможных интересных вещей, включая поиск удерживаемых замков. Вы не можете получить реальный объект, но вы получите хеш-значение класса и идентификатора (которое не является уникальным).

В одном из моих блогов есть пример.

4 голосов
/ 09 сентября 2008

Выполнить jconsole . Он включен в Java SDK и запускается из командной строки. Я не уверен, какую ОС вы используете, но в Windows вы можете просто передать ему PID процесса Java. Это должно помочь вам найти нить, которая вызывает проблему. Или вы можете использовать коммерческий профилировщик, например YourKit, или любое другое количество профилировщиков.

3 голосов
/ 09 сентября 2008

В версии 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

1 голос
/ 11 июля 2015

если это блокировка повторного входа вы можете проверить, поддерживается ли она текущим потоком

final ReentrantLock lock = new ReentrantLock();
lock.isHeldByCurrentThread();
1 голос
/ 07 марта 2013

Вы можете проверить блокировку определенного объекта, вызвав метод wait() или notify() для этого объекта. Если объект не удерживает блокировку, он выбросит llegalMonitorStateException.

2 - вызывая метод holdsLock(Object o). Это вернет логическое значение.

0 голосов
/ 29 марта 2018

Ужасно, но работает.

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);
    }
}
0 голосов
/ 05 декабря 2011

Вы можете использовать переменную для хранения текущего потока, когда вы берете блокировку, а затем распечатать ее, если кто-то другой пытается ее использовать.

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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...