如何用Kotlin协程精准每分钟整点执行任务?
解决Kotlin协程定时任务漂移问题
你的代码出现时间漂移的原因是:每次执行完saveCachedValues()后才固定延迟1分钟,方法本身的执行耗时会被叠加到间隔中,导致后续执行时间越来越偏离预期的整分0秒。
要实现精准在每分钟0秒触发的定时任务,核心思路是:预先计算每次执行的精确目标时间,执行完成后延迟到该目标时间,而非固定延迟1分钟。
以下是修正后的代码:
private suspend fun saveCachedValuesPeriodically() { val now = System.currentTimeMillis() // 计算初始延迟,直到下一分钟的0秒 val secondsIntoMinute = (now / 1000) % 60 val initialDelay = if (secondsIntoMinute == 0L) 0L else (60 - secondsIntoMinute) * 1000 var nextRunTime = now + initialDelay // 等待首次执行时间 delay(initialDelay) while (currentCoroutineContext().isActive) { // 执行目标方法 saveCachedValues() // 更新下一次执行的目标时间(固定加60秒) nextRunTime += 60_000 val currentTime = System.currentTimeMillis() // 计算需要延迟的时长 val delayMs = if (nextRunTime > currentTime) { // 目标时间未到,延迟到目标时间 nextRunTime - currentTime } else { // 已错过目标时间,计算下一个有效整分0秒 val missedMinutes = ((currentTime - nextRunTime) / 60_000) + 1 nextRunTime += missedMinutes * 60_000 nextRunTime - currentTime } delay(delayMs) } }
代码说明:
- 初始延迟计算:通过当前时间计算到下一分钟0秒的等待时长,确保首次执行精准对齐整分0秒。
- 跟踪目标执行时间:用
nextRunTime变量存储每次执行的精确时间戳,每次执行后固定增加60秒,保证间隔严格为1分钟。 - 自适应延迟调整:
- 如果
saveCachedValues()执行耗时较短,目标时间仍在未来,则延迟到该时间点。 - 如果方法执行耗时超过1分钟(错过目标时间),则自动计算跳过的分钟数,直接跳转到下一个有效整分0秒执行。
- 如果
这种方式无论方法执行耗时多久,都能保证后续执行始终对齐每分钟的0秒,彻底解决时间漂移问题。
内容的提问来源于stack exchange,提问作者amp
相关产品推荐
相关产品推荐

