2011-06-22 32 views
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); 

有没有更好的方法?

回答

5

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

+0

哦,我以前做过。感谢您的提醒。 –

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

谢谢,好主意! –