在ScheduledThreadPoolExecutor中抑制冗余作业

时间:2012-08-08 12:46:18

标签: java scheduled-tasks scheduling

我正在使用ScheduledThreadPoolExecutor来执行定期任务。 执行必须是周期性的,且具有固定的延迟。

我遇到了以下问题:考虑一个任务1分钟的时间。如果任务需要5分钟执行(例如,由于临时网络问题),错过的执行将排队并在任务完成后立即分派。有没有办法摆脱错过的累积执行?

我尝试使用remove方法,但它完全删除了任务,而不仅仅是特定的执行。

由于

3 个答案:

答案 0 :(得分:2)

可能有更好的方法,但您可以让自己的任务重新安排。这样,一次执行将始终在上一次执行完成后1分钟运行:

final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable yourTask = new Runnable() {

    @Override
    public void run() {
        //do your stuff
        scheduler.schedule(this, 1, TimeUnit.MINUTES);
    }
};
scheduler.schedule(yourTask, 1, TimeUnit.MINUTES);

编辑

如果您希望任务完全按照hh:mm:00(确切分钟)运行,则可以通过

替换代码
long millisToNextMinute = 60000 - System.currentTimeMillis() % 60000;
scheduler.schedule(this, millisToNextMinute, TimeUnit.MILLISECONDS);

答案 1 :(得分:1)

您可以将此逻辑构建到任务中。让任务记录上次运行。每次启动时,都应该检查自上次运行以来是否已经过了足够的时间。如果没有,那么它应该退出而不做任何工作。

答案 2 :(得分:0)

CronScheduler中,有SkippingToLatest个方法(请参阅Javadocs,“跳到最新运行”部分,专门为您解决此问题:

Duration syncPeriod = Duration.ofMinutes(1);
CronScheduler cron = CronScheduler.create(syncPeriod);
cron.scheduleAtFixedRateSkippingToLatest(0, 1, TimeUnit.MINUTES, runTimeMillis -> {
    // Do your task
});