ScheduledExecutorService用于在异常后保留的任务

时间:2018-05-17 19:20:01

标签: java task scheduling scheduledexecutorservice

scheduleAtFixedRate() ScheduledExecutorServicescheduleWithFixedDelay()Java方法的文档说明,对于任何计划任务,“如果任务的任何执行遇到异常随后的处决被压制。“。

是否有任何方法可以使用这两种方法具有相同的功能,但即使在任务中发生异常后仍然存在(除了手动抑制该异常)?

1 个答案:

答案 0 :(得分:0)

不仅使用这些方法,还可以轻松地使自己的计划执行程序有效地回避该行为。我没有尝试编译它,但是作为第一个步骤。

public final class KeepOnChuggingExecutor implements ScheduledExecutorService {
    private final ScheduledExecutorService scheduledExecutorService;
    

    public KeepOnChuggingExecutor(ScheduledExecutorService scheduledExecutorService) {
        this.scheduledExecutorService = scheduledExecutorService;
    }

    // Handle any exceptions in tasks
    private Runnable wrapRunnable(Runnable runnable) {
        return () -> {
            try {
                runnable.run();
            }
            catch (Exception e) {
                // Log it if you want to
            }
        };
    }

    private Callable<V> wrapCallable(Callable<V> callable) {
        return () -> {
            try {
                return callable.call();
            }
            catch (Exception e) {
                // Log it if you want to
            }
        };
    }

    // And then for every interface method on scheduled executor, wrap the
    // given task so that exceptions don't bubble up.
    @Override
    public ScheduledFuture<?> schedule​(Runnable command, long delay, TimeUnit unit) {
        return this.scheduledExecutorService.schedule(
            this.wrapRunnable(command),
            delay, 
            unit
        );
    }

    @Override
    public <V> ScheduledFuture<V> schedule​(Callable<V> callable, long delay, TimeUnit unit) {
        return this.scheduledExecutorService.schedule(
            this.wrapCallable(callable),
            delay,
            unit
        );
    }


    // And so on for all the scheduled methods. Then the rest of the methods in
    // Executor you can just delegate to the service this class wraps.

    // ...

    @Override
    public boolean isTerminated() {
        return this.scheduledExecutorService.isTerminated();
    }
    // ...

}

因此,这里的一般解决方案是“合成”模式。它很冗长,并且您确实会重复自己的操作,但是你们都不能为避免执行重复而任意继承一个执行器,并且可能不想这样做(除非您落入所有关注继承和哭泣的人的命运)

您仍然需要抑制该异常,但是将工作移出任务定义可以带来一些好处。