从在 ScheduledExecutorService 中运行的任务本身中停止定期任务

在 ScheduledExecutorService 中运行时,有没有一种很好的方法来阻止任务本身的重复?

比方说,我有以下任务:

Future<?> f = scheduledExecutor.scheduleAtFixedRate(new Runnable() {
    int count = 0;
    public void run() {
       System.out.println(count++);
       if (count == 10) {
           // ??? cancel self
       }
    }
}, 1, 1, TimeUnit.SECONDS);

从外面看,通过f.cancel()取消很容易,但是我该如何在指定的地方停止重复呢?(通过原子引用传递未来是不安全的,因为当调度AtFixedRate延迟返回f并且变量也设置延迟时,存在一个潜在的窗口,并且任务本身可能已经运行,在引用中看到空值。


答案 1

当重复任务引发异常或错误时,该任务将放置在“将来”中,并且该任务不会再次重复。您可以抛出您选择的运行时异常或错误。


答案 2

您可以使用命名类,而不是使用匿名内部类,该类可以具有您在计划任务时从中获取的对象的属性。FutureExecutor

abstract class FutureRunnable implements Runnable {

    private Future<?> future;

    /* Getter and Setter for future */

}

计划任务时,可以将 传递给 。FutureRunnable

FutureRunnable runnable = new FutureRunnable() {

    public void run() {
        if (/* abort condition */)
            getFuture().cancel(false);
    }

};
Future<?> future = executor.scheduleAtFixedRate(runnable, ...);
runnable.setFuture(future);

也许您必须确保在设置之前未执行任务,因为否则您将获得.FutureNullPointerException


推荐