2015-05-06 1 views
1

У меня есть WatchService, что бросает ClosedWatchServiceException на следующий код:Как остановить WatchService при завершении работы приложения?

final WatchService watchService = FileSystems.getDefault().newWatchService(); 

Runtime.getRuntime().addShutdownHook(new Thread() { 
    public void run() { 
     try { 
      watchService.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
}); 

WatchKey key = null; 
while (true) { 
    key = watchService.take(); //throws ClosedWatchServiceException 
    //execution 
} 

Как мне выключить службу безопасности, не получив исключение? Или я должен пренебрегать выключением, так как любые нити будут убиты при завершении приложения?

ответ

3

Первое примечание, что в коде нет ничего плохого. Вы просто должны обрабатывать ClosedWatchServiceException изящно во время выключения. Это связано с тем, что поток, выполняющий watchService.take(), блокируется в этой операции во время выполнения shutdown jvm. Таким образом, заблокированный поток будет разблокирован, как только служба часов будет закрыта.

Вы можете предотвратить это, прервав нить, которая работает watchService.take(), до вызова watchService.close(). Это должно дать вам InterruptedException, с которым вы можете справиться. Но контракт take ничего не говорит о порядке событий, которые принимаются во внимание при выбросе исключения. Таким образом, вы все равно можете получить ClosedWatchServiceException.

Таким образом, у вас может быть флаг volatile, указывающий на выключение приложения. После ловли ClosedWatchServiceException вы можете оценить флаг, а затем выйти изящно, если флаг установлен.