Может ли запущенный поток стать работоспособным при входе в неоспоримый синхронизированный блок?

Странная вещь происходя на нашей коробке продукции.
Функциональность кода:
Сервлет пользовательского интерфейса принимает блокировку монитора на объекте документа, на который действует пользователь, и выполняет некоторые вычисления над ним. Блокировка монитора приобретается для предотвращения одновременного изменения одного и того же объекта документа несколькими пользователями.

Проблема, наблюдаемая в Prod:
Несколько действий пользователя получают тайм-аут.

Анализ Журнала:
Поток, соответствующий действиям пользователя с истекшим временем ожидания, печатает все журналы перед получением блокировки монитора на объекте документа. Затем есть промежуток более 1 часа, где поток не всплывает в журналах, а затем он внезапно становится живым и делает вычисление и пытается отправить ответ, который, очевидно, ошибается, поскольку HTTP-запрос уже истек.
Мы проверили журналы и код и можем подтвердить, что нет никакого другого потока, который получил блокировку монитора на этом конкретном объекте документа. Таким образом, замок был неоспорим в данный момент.

Какой может быть возможный вопрос? Это просто, что поток был введен в работоспособное состояние при встрече синхронизированного блока и в течение следующих 60-80 минут, ЦП никогда не получил шанс запустить этот конкретный работоспособный поток?

1 ответ

  1. Убедитесь, что код приложения не возится с приоритетом потока с помощью Thread.setPriority()метода или тому подобного. Если вы используете IDE, такую как IntelliJ, и источники Java доступны, и предполагая, что вы можете запустить приложение и соответствующий поток локально в вашей машине разработки, вы можете поместить точку останова, Thread.setPriority()чтобы увидеть, если где-то он вызывается. Это выдержка из Java Concurrency in Practice, Goetz 2006, о том, как непредсказуемое поведение может быть, если вы пытаетесь установить приоритет потока вручную:

    10.3.1. Голод
    Голодание происходит, когда потоку постоянно отказывают в доступе к ресурсам, необходимым для достижения прогресса;
    обычно голодают ресурсов процессора циклов. Голодание в Java-приложениях может быть вызвано неправильным использованием потока
    приоритеты. Это также может быть вызвано выполнением нетерминирующих конструкций (бесконечные циклы или ожидания ресурсов, которые не
    terminate) с удерживаемой блокировкой, так как другие нити, которым нужна эта блокировка, никогда не смогут ее получить.
    Приоритеты потока, определенные в API потока, являются просто подсказками по планированию. API потока определяет десять уровней приоритета
    что JVM может сопоставить с приоритетами планирования операционной системы, как он считает нужным. Это сопоставление является платформой specific, поэтому два
    Приоритеты Java могут сопоставляться с тем же приоритетом ОС на одной системе и различными приоритетами ОС на другой. Некоторые работая
    системы имеют менее десяти уровней приоритета, в этом случае несколько приоритетов Java сопоставляются с тем же приоритетом ОС.
    Планировщики операционной системы идут к большим длинам для того чтобы обеспечить запланировать справедливость и liveness за то требуемое
    Спецификация Языка Java. В большинстве приложений Java все потоки приложений имеют одинаковый приоритет, Thread.
    NORM_PRIORITY. Механизм приоритета резьбы является тупым инструментом, и не всегда очевидно, какой эффект меняется
    приоритеты будут иметь; повышение приоритета потока может ничего не сделать или всегда может привести к назначению одного потока в
    предпочтение другим, вызывающим голод.
    Обычно разумно противостоять искушению изменить приоритеты потоков. Как только вы начнете изменять приоритеты,
    поведение вашего приложения становится специфичным для платформы, и вы вводите риск голодания. Вы можете часто определять
    программа, которая пытается восстановить от приоритетной настройки или других проблем отзывчивости по наличию
    Нитки.сон или нить.вызовите вызовы в нечетных местах, чтобы дать больше времени для более низкого приоритета потоков.[5]