优雅的非线性任务调度?

时间:2011-06-22 14:44:56

标签: java executorservice

我想安排一项任务首先经常发生,然后不经常发生。我宁愿不为此添加一个依赖到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 );

有更优雅的方法吗?

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分: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()) {
        ...          
      }
    }
  }
}