2013-11-23 5 views
4

В полезной библиотеке я создаю ExecutorServiceShutdown ExecutorService грациозно, когда главный-нить завершает

ExecutorService es = Executors.newSingleThreadExecutor(); 

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

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

ответ

5

Используйте Runtime#addShutdownHook(), чтобы добавить привязку выключения к текущему времени выполнения.

E.g.

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     es.shutdown(); 
     try { 
      es.awaitTermination(5, TimeUnit.SECONDS); 
     } catch (InterruptedException e) { 
      logger.info("during await",e); 
     } 
    } 
}); 

Сделайте это при создании/инициализации вашего служебного класса.

+0

Почти работал. :) Если основной поток достаточно хорош, чтобы вызвать System.exit (0); в конце исполнения. Однако пользователям этой библиотеки нельзя доверять :( –

+0

Если конечный пользователь не хочет изящно завершить работу, ему нечего делать. Microsoft, к примеру, знает это очень хорошо. Лучшее, что вы можете сделать, это сохранить некоторые информацию о процессах где-то в [пользовательских префайлах] (http://docs.oracle.com/javase/7/docs/api/java/util/prefs/Preferences.html) и искать ее, когда программа запускается снова, а затем в конечном итоге сообщите пользователю, как в «Программа, кажется, неожиданно закончилась во время предыдущего запуска, вот некоторые незавершенные процессы [...], вы хотите повторно запустить их?» и т. д. – BalusC

+0

Возможно, есть какой-то способ узнать, что main-thread ничего не осталось выполнить? –

3

shutdownHook не будет работать, если вы не сделаете своего исполнителя потоком демона. Вот причина:

shutdownhook запускается при запуске JVM, и JVM не выйдет, если вы не вызываете es.shutDown(), так что это тупик.

Я не знаю, почему создание демона-исполнителя не сработало. Должно. Демон исполнитель не завершение работы, пока все темы от основного класса не закончили выполнения (если они не являются также демоном)

попробовать этот код при создании исполнителя

ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFactory() { 
     @Override 
     public Thread newThread(Runnable r) { 
      Thread t = new Thread(r); 
      t.setDaemon(true); 
      return t; 
     } 
    }); 
Смежные вопросы