Отладка ReentrantReadWriteLock Deadlock в Eclipse
У меня есть приложение, которое иногда блокируется (скажем, раз в месяц).
Прямо сейчас мне удалось воспроизвести это условие во время работы в отладчике затмения.
Кажется, что все потоки ожидают освобождения WriteLock.
Что мне нужно, так это способ выяснить, какой из 200 потоков удерживает блокировку.
Но приостановка потоков в eclipse и проверка не дали результатов, потому что eclipse говорит мне, что не может получить доступ к переменным, которые я хочу просмотреть, потому что поток был приостановлен вручную.
Я не хочу перезапускать приложение, потому что я не знаю, смогу ли я попасть в этот тупик во второй раз.
Так что же делать, чтобы найти держатель замка?
РЕДАКТИРОВАТЬ: я уже пробовал jstack, чтобы сделать мне поток дампа. Но я могу только найти потоки, ожидающие блокировки, но не удерживающие ее.
1 ответ
Проблема здесь в том, что нам нужно заставить приложение достичь «нормальной» точки останова.
Есть несколько разных способов сделать это. Во всех случаях новая точка останова должна приостановить всю программу (IntelliJ может это сделать, и я предполагаю, что Eclipse тоже может).
-
Object#wait
(точка останова на входе методаpublic final native void wait (long timeout)
) -
Unsafe#;park
(точка останова на входе методаpublic native void park(boolean isAbsolute, long time)
) - Если у вас есть поток, который постоянно выполняет работу (например, получает удаленные данные), добавьте точку останова в этот код.
Как только это произойдет, вы можете (в IntelliJ IDEA и, предположительно, в Eclipse) переключить потоки на интересующие потоки и оттуда выполнить отладку.
В IntelliJ IDEA мне удалось сделать следующее:
final Thread ownerThread = ((ReentrantReadWriteLock.WriteLock) lock.writeLock()).sync.getExclusiveOwnerThread();