版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lsshlsw/article/details/79101772
定时器中 Timer 有单线程等缺陷,quartz依赖太重, 用 ScheduledThreadPoolExecutor 又想实现定时调度,实现一个工具类计算初次调度时间即可。
import java.util.concurrent._
val task = new Runnable {
override def run(): Unit = try {
doSomething()
}catch {
case e: Exception => e.printStackTrace()
}
}
val ex = new ScheduledThreadPoolExecutor(1)
//晚上10点半开始调度,每天调度一次
ex.scheduleAtFixedRate(task, DateHelper.calcDelay(22, 30, 0), DateHelper.ONE_DAY, TimeUnit.SECONDS)
DateHelper
import java.util.Calendar
object DateHelper {
val ONE_DAY = 60 * 60 * 24
/**
* 计算下次调度开始的时间,单位为秒,24小时制
**/
def calcDelay(hour: Int, minute: Int, second: Int): Long = {
if (!(0 <= hour && hour <= 23 && 0 <= minute && minute <= 59 && 0 <= second && second <= 59)) {
throw new IllegalArgumentException()
}
val curTime = getCurTime()
val targetTime = getTargetTime(hour, minute, second)
//如果已经过了执行时间,执行时间变更为下一天该时段
val delayTime = if (curTime < targetTime) {
targetTime - curTime
} else {
val cal = Calendar.getInstance()
cal.setTimeInMillis(targetTime)
cal.add(Calendar.DATE, 1)
cal.getTimeInMillis - curTime
}
delayTime / 1000
}
//获取当前的时间
private def getCurTime(): Long = {
val cal = Calendar.getInstance()
cal.getTimeInMillis
}
//获取下次执行的时间
private def getTargetTime(hour: Int, minute: Int, second: Int): Long = {
val cal = Calendar.getInstance()
cal.set(Calendar.HOUR_OF_DAY, hour)
cal.set(Calendar.MINUTE, minute)
cal.set(Calendar.SECOND, second)
cal.getTimeInMillis
}
}