异常抑制进一步执行后 ScheduledFuture 的状态

State of ScheduledFuture after exception has suppressed further execution

scheduleAtFixedRate()scheduleWithFixedDelay()ScheduledExecutorService 的文档说:

If any execution of the task encounters an exception, subsequent executions are suppressed

也许是一个简单的问题,但我如何以编程方式检测到这已经发生(不调用 ScheduledFuture.get())? isCancelled() 返回 true 是否反映了这种情况?

为了回答这个问题,我写了一个小单元测试:

import static org.assertj.core.api.BDDAssertions.then;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;

class ScheduledExecutorServiceLT {
    
    @Test
    void test() throws InterruptedException {
        
        final AtomicInteger counter = new AtomicInteger();
        
        final ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
        
        final ScheduledFuture<?> scheduledFuture = scheduledExecutor.scheduleWithFixedDelay(() -> {
            if (counter.incrementAndGet() == 3) {
                throw new RuntimeException();
            }
        }, 0L, 100L, TimeUnit.MILLISECONDS);

        then(scheduledFuture.isCancelled()).isFalse();
        then(scheduledFuture.isDone()).isFalse();
        
        Thread.sleep(500L);
        
        then(counter.get()).isEqualTo(3);
        then(scheduledFuture.isCancelled()).isFalse();
        then(scheduledFuture.isDone()).isTrue();
    }
}

结论:

  • 发生异常后Runnable不会再执行
  • 与我的预期相反,已取消 保持 false,但
  • 完成 变为 true,如果引发异常