Как закрыть всех исполнителей при выходе из приложения? - PullRequest
10 голосов
/ 31 июля 2009

Согласно практическому параллелизму Java Брайана Гетца JVM не может выйти до тех пор, пока не прекратятся все потоки (не являющиеся демонами), поэтому сбой в работе Executor может помешать выходу JVM. т.е. System.exit (0) не обязательно работает должным образом, если вокруг есть Executors. Казалось бы надо поставить какую-то

public void stop() { exec.shutdown() }

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

Ответы [ 5 ]

14 голосов
/ 31 июля 2009

Там нет ярлыка, чтобы сделать их все, нет. Кроме того, вам, вероятно, следует позвонить shutdownNow(), а не shutdown(), иначе вы могли бы подождать некоторое время.

То, что вы могли бы сделать, я полагаю, это когда вы создаете Исполнителя, регистрируете его в центральном месте. Затем, при выключении, просто вызовите shutdown() на этом центральном объекте, который, в свою очередь, может завершить работу каждого из зарегистрированных исполнителей.

Если вы используете Spring, то можете воспользоваться его фабричными компонентами, которые создают и управляют исполнителями для вас. Это включает в себя корректное отключение при выходе из приложения и избавляет вас от необходимости управлять ими самостоятельно.

9 голосов
/ 07 февраля 2013

Украсьте исполнителя com.google.common.util.concurrent.MoreExecutors # getExitingExecutorService

@Beta
public static ExecutorService getExitingExecutorService(ThreadPoolExecutor executor,
                                         long terminationTimeout,
                                         TimeUnit timeUnit)

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

Это в основном для фиксированных пулов потоков. См. Executors.newFixedThreadPool (int).

8 голосов
/ 06 апреля 2011

По умолчанию Исполнитель будет создавать только нити-демоны. Вы можете переопределить это, предоставив Исполнителю свой собственный ThreadFactory. Вот пример:

class DaemonThreadFactory implements ThreadFactory {
  public Thread newThread(Runnable r) {
    Thread t = new Thread(r);
    t.setDaemon(true);
    return t;
  }
}

Будьте осторожны, потому что JVM сразу выйдет , даже если эти потоки заняты выполнением полезной работы!

5 голосов
/ 31 июля 2009

Вы также можете предоставить реализацию ThreadFactory, которая помечает созданные потоки как потоки демона. Я предпочитаю механизм чистого отключения (с методами жизненного цикла), но в некоторых случаях вам не нужны гарантии о состоянии / завершении незавершенных задач, когда это может быть уместно.

0 голосов
/ 31 июля 2009

Вероятно, он хотел сказать, что JVM не может остановиться самостоятельно до тех пор, пока не завершатся не-демонические потоки. Это все равно что запускать простой класс из команды, такой как java SomeClass, и после выполнения основного метода JVM останавливается.

System.exit - это команда завершения JVM, даже если запущены потоки демона, JVM завершит работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...