ScheduledThreadPoolExecutor 定時排程
阿新 • • 發佈:2018-12-13
定時器中 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
}
}