Подтвердить что ты не робот

Почему ScheduledExecutorService не запускает задачу снова после исключения исключения?

Для выполнения периодических задач я просмотрел Timer и ScheduledThreadPoolExecutor (с одним thread) и решил использовать последнее, потому что в reference for Executors.newSingleThreadScheduledExecutor() он говорит:

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

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

Здесь код:

@Test
public void testTimer() {
    final AtomicInteger cTries = new AtomicInteger(0);
    final AtomicInteger cSuccesses = new AtomicInteger(0);

    TimerTask task = new TimerTask() {
        @Override
        public void run()
        {
            cTries.incrementAndGet();
            if (true) {
                throw new RuntimeException();
            }
            cSuccesses.incrementAndGet();
        }
    };

    /*
    Timer t = new Timer();
    t.scheduleAtFixedRate(task, 0, 500);
     */
    ScheduledExecutorService exe = Executors.newSingleThreadScheduledExecutor();
    exe.scheduleAtFixedRate(task, 0, 500, TimeUnit.MILLISECONDS);
    synchronized (this) {
        try {
            wait(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
    exe.shutdown();
    /*
    t.purge();
     */
    Assert.assertEquals(cSuccesses.get(), 0);
    Assert.assertTrue(cTries.get() > 1, String.format("%d is not greater than 1. :(", cTries.get()));
}
4b9b3361

Ответ 1

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

Вы должны поймать Исключения, если вы не хотите убивать повторяющуюся задачу.


Поскольку матовый b указывает в комментарии выше,

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

Ответ 2

матовый b дал причину.

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



Следует отметить, что написано в документации ScheduledExecutorService

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

И как говорит Майкл Круссе, вопрос о создании нового потока - позволить другим задачам продолжать работу.