Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 优雅的非线性任务调度?_Java_Executorservice - Fatal编程技术网

Java 优雅的非线性任务调度?

Java 优雅的非线性任务调度?,java,executorservice,Java,Executorservice,我想先安排一项任务频繁地进行,然后随着时间的推移减少。我不希望仅仅为了这个而向Quartz添加依赖项 对于标准Java库,我想到的最好方法是一系列一次性任务,然后是一个不太频繁的线性计划: ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); myRunnable = new MyRunnable(); executor.schedule( myRunnable, 0, TimeU

我想先安排一项任务频繁地进行,然后随着时间的推移减少。我不希望仅仅为了这个而向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 );

是否有更优雅的方法?

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

作为@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);
  }
}
还请注意,
中继器
不是匿名的
可运行的
,它可以成为一种公开的类型,允许取消未来的调度,等等:

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()) {
        ...          
      }
    }
  }
}