У меня есть Runnable
, который работает от Executor
.
Запуск заблокирован в ожидании в SychronousQueue.take
. Как я могу убедиться, что take
будет прерван, если я сделаю executor.shutdown
?Прерывание при ожидании в очереди блокировки
ответ
+1 для @Eugene. ExecutorService.shutdown()
отключает пул потоков вниз, но любые отправленные задания будут продолжать работать до тех пор, пока они не закончатся. Если вместо этого вы используете shutdownNow()
, это фактически прервет потоки. Это не означает, что они будут немедленно останавливаться, но это означает, что если они заблокированы в queue.take()
или их следующий вызов queue.take()
, он выкинет InterruptedException
, чтобы поток мог выйти.
Цитата из Javadocs:
Попытки остановить все активно выполняющиеся задачи, останавливает обработку ожидающих задач, и возвращает список задач, которые ожидают выполнения.
Отсутствие гарантий, кроме попыток максимального усилия по прекращению обработки, активно выполняющей задачи. Например, типичные реализации будут отменены через Thread.interrupt(), поэтому любая задача, которая не отвечает на прерывания, может никогда не прекратиться.
Когда ваши потоки вызова queue.take()
они должны иметь что-то вроде следующего кода:
try {
work = queue.take();
...
} catch (InterruptedException e) {
// re-interrupt the thread which is always a good pattern
Thread.currentThread().interrupt();
// quit the processing thread
return;
}
Вы можете сделать что-то вроде этого?
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIME)) {
executor.shutdownNow();
}
Как указано в javadoc of take он будет бросать InterruptedException
когда ожидающий поток прерывается. Поэтому вам нужно убедиться, что ваша реализация исполнителя вызовет Thread.interrupt() во всех своих потоках на shutdown
.
shutdownNow? возможно, – Eugene
ShutdownNow просто не выполняет остальные задачи. Проблема заключается в том, что произойдет, когда поток заблокирован на 'take' – Jim
Дело в том, что SynchronousQueue, вероятно, пуст, поэтому take() будет блокировать, пока не произойдет put() , Можете ли вы заменить его LinkedBlockingQueue? – Eugene