Обработка исключений ScheduledExecutorService

Я использую ScheduledExecutorService для запуска потоков с фиксированным интервалом 1 min.

Один экземпляр ScheduledExecutorService запускает один поток, а другой экземпляр запускает другой поток.

Пример:

ses1.scheduleAtFixRate(..) // for thread 1  
ses2.scheduleAtFixRate(..) // for thread 2

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

Должен ли я обрабатывать исключение с помощью третьего потока, который отслеживает оба фьючерса и обрабатывает исключение, или есть другой лучший способ? Повлияет ли это на другие потоки.

Любая помощь приветствуется!


person Sanyam    schedule 03.08.2019    source источник


Ответы (1)


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

Это ожидаемое поведение ScheduledExecutorService.scheduleAtFixRate() в соответствии со спецификацией:

Если какое-либо выполнение задачи сталкивается с исключением, последующие выполнения подавляются.

О вашей потребности:

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

Обработка будущего возврата с помощью ScheduledFuture.get() выглядит правильно. Согласно спецификации ScheduledFuture.scheduleAtFixedRate():

В противном случае задача будет завершена только через отмену или прекращение исполнителя.

Таким образом, вам даже не нужно создавать новое запланированное будущее.
Просто запустите две параллельные задачи (с ExecutorService или двумя потоками также возможны), которые ожидают get() каждого Future и останавливают приложение в случае возникновения исключения. задание :

Future<?> futureA = ses1.scheduleAtFixRate(..) // for thread 1  
Future<?> futureB = ses2.scheduleAtFixRate(..) // for thread 2
submitAndStopTheApplicationIfFail(futureA);
submitAndStopTheApplicationIfFail(futureB);

public void submitAndStopTheApplicationIfFail(Future<?> future){
      executor.submit(() -> {
      try {
        future.get();
      } catch (InterruptedException e) {
        // stop the application
      } catch (ExecutionException e) {
        // stop the application
      }
    });
}
person davidxxx    schedule 03.08.2019
comment
Таким образом, он застревает на future1.get(). Если второй поток столкнется с исключением, этот метод не будет работать. Он будет ждать завершения первого потока. - person Sanyam; 03.08.2019
comment
Это правильно. Они должны быть в своем собственном потоке выполнения, чтобы .get() не блокировалось. я обновил. Подскажите лучше ли. - person davidxxx; 03.08.2019
comment
Сделал то же самое, пока чинил, но спасибо. Большая помощь. - person Sanyam; 03.08.2019