0

我想安排一个任务一开始经常发生,然后随着时间的推移减少频率。我不希望仅仅为此添加对 Quartz 的依赖项。

使用标准 Java 库,我想出的最好的方法是一系列一次性任务,然后是频率较低的线性计划:

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    myRunnable = new MyRunnable();
    executor.schedule( myRunnable, 0, TimeUnit.SECONDS );
    executor.schedule( myRunnable, 5, TimeUnit.SECONDS );
    executor.schedule( myRunnable, 10, TimeUnit.SECONDS );
    executor.schedule( myRunnable, 15, TimeUnit.SECONDS );
    executor.schedule( myRunnable, 30, TimeUnit.SECONDS );
    executor.schedule( myRunnable, 45, TimeUnit.SECONDS );
    executor.scheduleWithFixedDelay( myRunnable, 60, 300, TimeUnit.SECONDS );

有没有更优雅的方法?

4

2 回答 2

5

您可以让任务触发其下一次执行,并在每次完成后总是增加一些“等待秒数”吗?

于 2011-06-22T14:56:55.427 回答
2

作为@dcn 建议的扩展,您可以编写一个执行调度的委托类:

public class NonLinearScheduling {

  public static void taperingOffSchedule(final ScheduledExecutorService executor,
                                         final Runnable task,
                                         final long initialDelay,
                                         final TimeUnit unit,
                                         final double decayMultiplier) {
    assert initialDelay > 0;
    assert decayMultiplier > 1.0;
    Runnable repeater = new Runnable() {
        double nextDelay = initialDelay;
        public void run() {
            task.run();
            nextDelay *= decayMultiplier;
            executor.schedule(this, (long) nextDelay, unit);
        }
    };
    executor.schedule(repeater, initialDelay, unit);
  }
}

另请注意,它可以成为一个公开的类型,而不是repeater一个匿名Runnable的类型,允许取消未来的调度,等等:

public interface Repeater extends Runnable {
  void stopRepeating();
}


public class NonLinearScheduling {
  public static Repeater taperingOffSchedule(...) { ... }

  private static class NonLinearRepeater implements Repeater {
    private final AtomicBoolean _repeat = new AtomicBoolean(true);

    public void stopRepeating() {
      _repeat.set(false);
    }

    public void run() {
      if (_repeat.get()) {
        ...          
      }
    }
  }
} 
于 2011-06-22T15:29:57.710 回答