Как обнаружить мертвую блокировку? Тайм-аут в синхронизируемом блоке?

Попробуйте на Python:

>>> int('1' * 31, base=2)
2147483647
14
задан z - 28 July 2009 в 15:11
поделиться

6 ответов

Вы можете использовать java.util.concurrent.Lock вместо внутренних блокировок объекта . RentrantLock без справедливого упорядочивания имеет то же базовое поведение и семантику, что и внутренняя блокировка. Существует метод tryLock , который принимает параметр тайм-аута:

Lock lock = ...;
if (lock.tryLock(10L, TimeUnit.SECONDS)) {
    try {
        // manipulate protected state
    } finally {
        lock.unlock();
    }
} else {
      // perform alternative actions
}
27
ответ дан 1 December 2019 в 06:54
поделиться

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

Один из вариантов - использовать что-то вроде JConsole (поставляется с JDK), который включает кнопку «Обнаружить тупик» (по крайней мере, в Java 6, я не думаю, что это работает в Java 5). Другой вариант - сгенерировать дамп потока в консоль - в Unix вы можете набрать «kill -3», в то время как в Windows подойдет сочетание клавиш CTRL + BRK. Другие инструменты профилирования, такие как VisualVM (также входящие в состав JDK), могут помочь.

10
ответ дан 1 December 2019 в 06:54
поделиться

Вы можете сделать так, чтобы потоки совместно использовали явную блокировку (см. Java.util.concurrent.lock.Lock). Затем вы можете использовать Lock.tryLock (), который может принимать необязательный тайм-аут.

Вы также можете использовать утилиту jstack, которая поставляется с java 1.6 (не уверен насчет 1.5), которая распечатает состояние всех ваших потоков и чего они могут, а могут и не ждать. Просто вызовите его с идентификатором процесса. например. :

  > jstack PID 

        "Signal Dispatcher" daemon prio=10 tid=0x00000000408e8400 nid=0x79a8 runnable [0x0000000000000000..0x000000004143f810]
           java.lang.Thread.State: RUNNABLE

        "Finalizer" daemon prio=10 tid=0x00000000408c9400 nid=0x79a7 in Object.wait() [0x0000000041a7b000..0x0000000041a7bb00]
           java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
            - locked <0x00007f992d1e7050> (a java.lang.ref.ReferenceQueue$Lock)
            at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
            at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

        "Reference Handler" daemon prio=10 tid=0x00000000408c2000 nid=0x79a6 in Object.wait() [0x000000004197a000..0x000000004197ac80]
           java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)
            at java.lang.Object.wait(Object.java:485)
            at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
            - locked <0x00007f992d41a958> (a java.lang.ref.Reference$Lock)
2
ответ дан 1 December 2019 в 06:54
поделиться

Вы не можете использовать тайм-ауты с традиционно синхронизированными методами. Однако, используя «новый» материал java.util.concurrent, вы можете использовать программные блокировки с поддержкой тайм-аута.

Например, посмотрите java.util.concurrent.locks.ReentrantLock

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

1
ответ дан 1 December 2019 в 06:54
поделиться

Может быть 2 причины: 1) умерла нить 2) Поток где-то заблокирован или делает что-то, чего вы не ожидали.

Лучшее решение - всегда использовать отладчик (дождаться возникновения ситуации, а затем приостановить приложения) или использовать JConsole / JStack / JVisualVM.

1
ответ дан 1 December 2019 в 06:54
поделиться

Хотя возможны тайм-ауты при ожидании блокировок для синхронизированных методов, их реализация является громоздкой. Обычно вы создаете поток таймера, который прерывает поток блока через T секунд ... не очень хорошо.

Если вы используете Java 5 или выше, я настоятельно рекомендую вам посмотреть, что предлагают новые классы параллелизма. Например, вы можете рассмотреть возможность использования ReentrantLock , у которого есть метод tryLock (длинный тайм-аут, единица TimeUnit) , который позволит вам попытаться получить блокировку, но позволит вам выйти после фиксированное количество времени.

0
ответ дан 1 December 2019 в 06:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: