ThreadPoolExecutor зависает

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

Нам нужно обновить некоторое состояние X ресурса Y на удаленном сервере. У нас есть менеджер ресурсов, который изменяет состояние ресурса и обновляет X как побочный эффект изменения. Этот менеджер постоянно опрашивает ресурс, и когда он считает, что ресурс обновлен, он использует ThreadPoolExecutor для выполнения работы. Этот исполнитель пула потоков имеет очередь блокировки разумного размера, но довольно небольшое максимальное количество потоков. Само зависание из дампа потока происходит в вызове invokeAll (среди прочего)

У нас есть основания полагать, что количество основных/максимальных потоков в этом исполнителе пула занято другими делами (больше обновлений состояния ресурсов, если хотите).

Поскольку invokeAll возвращает нам фьючерсы, которые мы ожидаем, вопрос заключается в том, зависает invokeAll, даже если блокирующая структура данных, используемая исполнителем, достаточно велика, чтобы принять работу, переданную через invokeAll, но нет достаточного количества доступных потоков?


person subramanian    schedule 23.11.2013    source источник


Ответы (1)


Как отметили другие пользователи, без некоторого кода (даже псевдокода) и более четкого понимания того, что такое «состояние X» и что такое «ресурс Y». , практически никто здесь не может дать разумный ответ. Короче говоря, вам нужен SSCCE. Тем не менее, я сделаю все возможное здесь ;-). И если вы сделаете почтовый код и / или предоставите дополнительную информацию, я соответствующим образом обновлю свой ответ.

Из Java 7 ExecutorService#invokeAll javadoc:

Выполняет заданные задачи, возвращая список фьючерсов со своим статусом и результатами, когда все завершено. Future.isDone() истинно для каждого элемента возвращаемого списка. Обратите внимание, что завершенная задача могла быть завершена как обычно, так и путем создания исключения. Результаты этого метода не определены, если данная коллекция изменяется во время выполнения этой операции.

По вашему описанию (опять же, я не могу точно сказать из-за отсутствия подробностей), один из ваших рабочих потоков завис. Поскольку вы вызываете invokeAll(...), исполнитель зависает, потому что ожидает завершения зависшего потока. Но этого никогда не происходит. Теперь, что касается того, почему вы получаете зависший поток, это совершенно другая проблема, и нам определенно нужно увидеть какой-то код. ХТН.

person IAmYourFaja    schedule 23.11.2013