2016-12-30 5 views
19

Ошибка при вызове shutdown() в исполнителе нитей приведет к тому, что приложение никогда не будет завершено. Лучшая практика, чтобы закрыть ExecutorService это:Почему интерфейс ExecutorService не реализует AutoCloseable?

ExecutorService service = null; 
try { 
    service = Executors.newSingleThreadExecutor(); 
    // Add tasks to thread executor 
    … 
} finally { 
    if(service != null) service.shutdown(); 
} 

Поскольку Java знает концепцию примерочных с-ресурсами, не будет ли хорошо, если бы мы могли это сделать?

try (service = Executors.newSingleThreadExecutor()) 
{ 
    // Add tasks to thread executor 
    … 
} 
+0

Хороший вопрос, хотя ... эта мысль мне никогда не приходила ;-) – GhostCat

+0

http://www.stackoverflow.com/questions/13883293/turning-an-executorservice-to-daemon-in-java –

+0

Есть тонны «находчивых» API-интерфейсов, отличных от 'Closeable', в JDK –

ответ

17

Это ExecutorService имеет фактически два остановленных связанных с методами; основанный на простом факте, что и способы закрытия службы имеют смысл.

Таким образом: как бы вы автоматически закрыли услугу? В последовательной манере, которая работает для всех ?!

Итак, разумное объяснение в моих глазах: вы не можете сделать ExecutorService автоматической блокировкой, потому что у этой службы нет единой операции «закрыть»; но два!

И если вы считаете, что можете использовать такое автоматическое закрытие, то написать свою собственную реализацию с помощью «делегирования» будет 5 минут! Или, вероятно, 10 минут, потому что вы создадите одну версию, вызывающую shutdown(), как близкую операцию; и тот, который делает shutdownNow().

+0

. Думаю, нам не нужно обсуждать аспекты реализации здесь. Я всегда чувствителен к использованию флагов (логических, как переключатели) для таких вещей. Но давайте не будем туда ... как я думаю, это будет довольно бесплодная дискуссия в конце. – GhostCat

+0

Возможно, вы правы;) То, что я действительно хотел сказать, заключается в том, что можно полностью включить функциональность «ExecutorService» в класс, который поддерживает «AutoCloseable» – ParkerHalo

+0

. Дополнительные аргументы, чтобы не сделать ExecutorService AutoClosable в JDK - это услуга, а не ресурс ... Точно такая же причина для ExceturService не расширять интерфейс Closeable. –

-1

Try-with-resources - это автоматическое закрытие Readers/Streams, где ExecutorService - это выполнение задач с использованием пула потоков.

Так что я не совсем уверен, есть ли параллель между двумя, что мы можем думать о применении try-with-resources к ExecutorServices.

ОБНОВЛЕНО
Цитирование Java Language Specification:

Заявление примерочного с-ресурсов параметризируются с переменными (известным как ресурсы), которые инициализируются перед выполнением блока Ьги и закрывается автоматически, в обратном порядок, с которого они были инициализированы, после выполнения блока try. catch и предложение finally часто не нужны, когда ресурсы автоматически закрываются.

Спецификация вызывает переменные как «Ресурсы». Так что я не уверен, что если ExecutorService может быть вызван в качестве ресурса и поэтому не думаю, что ExecutorService как параллель читателей/Streams/Заявление/ResultSet/Подключение и т.д.

9

Это посредственный обходной

ExecutorService service = Executors.newSingleThreadExecutor(); 
try (Closeable close = service::shutdown) { 

} 

Конечно, вы никогда не должны ставить что-либо между назначением и оператором try, а также не использовать локальную переменную service после инструкции try.

Учитывая оговорки, используйте вместо этого finally.

0

Я не вижу, где AutoCloseable является полезным для Исполнителя. try-with-resources - это вещи, которые могут быть инициализированы, использованы и выпущены в рамках метода. Это отлично подходит для таких вещей, как файлы, сетевые подключения, ресурсы jdbc и т. Д., где они быстро открываются, используются и быстро очищаются. Но исполнитель, особенно threadpool, - это то, что вы хотите использовать в течение длительного периода времени, возможно, в течение всего срока службы приложения и, как правило, впрыскивается в такие вещи, как singleton-сервисы, которые могут иметь метод, который инфраструктура DI знает вызовите выключение приложения, чтобы очистить исполнитель. Эта схема использования отлично работает без использования ресурсов try-with-resources.

Кроме того, большой мотиватор за попытками использования ресурсов гарантирует, что исключения не маскируются. Это не так много касается исполнителей, все бросание исключений будет происходить в задачах, переданных исполнителю, маскирование исключений не является проблемой.

Смежные вопросы