我正在使用ScheduledThreadPoolExecutor来执行定期任务。 执行必须是周期性的,不且具有固定的延迟。
我遇到了以下问题:考虑一个任务1分钟的时间。如果任务需要5分钟执行(例如,由于临时网络问题),错过的执行将排队并在任务完成后立即分派。有没有办法摆脱错过的累积执行?
我尝试使用remove方法,但它完全删除了任务,而不仅仅是特定的执行。
由于
答案 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
});