Java-демон - обработка запросов на выключение - PullRequest
2 голосов
/ 08 декабря 2009

В настоящее время я работаю над демоном, который будет выполнять ОЧЕНЬ много разных задач. Он многопоточный и создается для обработки практически любых внутренних ошибок без сбоев. Ну, я дошел до того, что обработал запрос на отключение, и я не уверен, как мне это сделать.

У меня есть настройка ловушки отключения, и когда она вызывается, она устанавливает переменную, сообщающую основному циклу демона о прекращении работы. Проблема в том, что этот демон порождает несколько потоков, и они могут занять много времени. Например, один из этих потоков может конвертировать документ. Большинство из них будут быстрыми (я полагаю, менее 10 секунд), но будут темы, которые могут длиться более 10 минут.

То, о чем я сейчас думаю, - это когда отправлено сообщение о завершении работы, сделать цикл в течение примерно 5 секунд для ThreadGroup.activeCount () со сном 500 мс (или около того) (все эти потоки находятся в ThreadGroup ) и перед этим циклом я отправлю всем потокам уведомление о том, что был вызван запрос на отключение. Тогда им придется немедленно, независимо от того, что они делают, очистить и закрыть.

У кого-нибудь еще есть предложения? Меня интересует, что делает, например, демон MySQL, когда ему приказывают остановиться, он останавливается мгновенно. Что произойдет, если будет запущено 10 очень медленных запросов? Ожидание или просто конец? Я имею в виду, что серверы действительно быстрые, поэтому на самом деле не существует никаких операций, которые я не смог бы выполнить менее чем за секунду. Вы можете сделать много в 1000 мс в наши дни.

Спасибо

Ответы [ 2 ]

2 голосов
/ 08 декабря 2009

Пакет java.util.concurrent предоставляет ряд утилит, таких как ThreadPoolExecutor (наряду с различными специализированными типами других Executor реализаций класса Executors) и ThreadPoolExecutor.awaitTermination(), на которые вы, возможно, захотите взглянуть - поскольку они предоставляют ту же самую функциональность, которую вы хотите реализовать. Таким образом, вы можете сосредоточиться на реализации фактической функциональности вашего приложения / задач, а не беспокоиться о таких вещах, как планирование потоков и задач.

1 голос
/ 08 декабря 2009

Подлежат ли прерывания задания потока через Thread#interrupt()? В основном они вызывают функции, которые сами рекламируют, выбрасывая InterruptedException? Если это так, то вышеупомянутый java.util.concurrent.ExecutorService#shutdownNow() - это путь. Он прервет все запущенные потоки и вернет список заданий, которые никогда не запускались.

Аналогичным образом, если вы зависаете с Future s, созданными ExecutorService#submit(), вы можете использовать Future#cancel(boolean) и передать true, чтобы запросить выполнение работ быть прерванным.

Если вы не вызываете из-под контроля код, который глотает сигналы прерывания (скажем, перехватывает InterruptedException без вызова Thread.currentThread().interrupt()), использование встроенного средства совместного прерывания является лучшим выбором, чем введение собственных флагов. приблизиться к тому, что уже есть.

...