一帕棉、schedule
public ScheduledFuture<?> schedule(Runnable command,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Void>(command, null,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
public <V> ScheduledFuture<V> schedule(Callable<V> callable,
long delay,
TimeUnit unit) {
if (callable == null || unit == null)
throw new NullPointerException();
RunnableScheduledFuture<V> t = decorateTask(callable,
new ScheduledFutureTask<V>(callable,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
- 不同的地方在于一個(gè)傳入的是Runnable類型香伴,一個(gè)傳入的是Callable<V>類型即纲,但是Runnable類型最終也會(huì)轉(zhuǎn)為Callable類型
- triggerTime是根據(jù)delay計(jì)算任務(wù)的執(zhí)行時(shí)間
private void delayedExecute(RunnableScheduledFuture<?> task) {
// 如果線程池關(guān)閉了低斋,拒絕任務(wù)
if (isShutdown())
reject(task);
else {
// 將任務(wù)加入到隊(duì)列
super.getQueue().add(task);
// 再判斷線程池狀態(tài)
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
// 啟動(dòng)任務(wù)
else
ensurePrestart();
}
}
void ensurePrestart() {
// 獲取工作線程數(shù)
int wc = workerCountOf(ctl.get());
// 啟動(dòng)核心線程
if (wc < corePoolSize)
// 因?yàn)檫@里是定時(shí)任務(wù)膊畴,所以這里firstTask為null
addWorker(null, true);
// 啟動(dòng)非核心線程
else if (wc == 0)
addWorker(null, false);
}
- 根據(jù)線程池狀態(tài)判斷是否取消任務(wù)
- Worker只是啟動(dòng)線程病游,最終執(zhí)行任務(wù)還是ScheduledFutureTask#run
public void run() {
// 判斷是不是周期性任務(wù),period != 0 就是周期性任務(wù)
boolean periodic = isPeriodic();
// 根據(jù)線程池狀態(tài)判斷是否需要取消任務(wù)
if (!canRunInCurrentRunState(periodic))
cancel(false);
// 如果是不是周期性任務(wù)买猖,執(zhí)行直接
else if (!periodic)
ScheduledFutureTask.super.run();
// 如果是周期性任務(wù),需要重置狀態(tài)
else if (ScheduledFutureTask.super.runAndReset()) {
// 設(shè)置下一次執(zhí)行的時(shí)間
setNextRunTime();
// 重新添加任務(wù)
reExecutePeriodic(outerTask);
}
}
二飞主、scheduleAtFixedRate與scheduleWithFixedDelay
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
if (delay <= 0)
throw new IllegalArgumentException();
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(-delay));
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
- scheduleAtFixedRate傳入的period是正數(shù)碌识,scheduleWithFixedDelay傳入的period是負(fù)數(shù)
private void setNextRunTime() {
long p = period;
if (p > 0)
time += p;
else
time = triggerTime(-p);
}
long triggerTime(long delay) {
return now() +
((delay < (Long.MAX_VALUE >> 1)) ? delay : overflowFree(delay));
}
- 由于scheduleAtFixedRate傳入的period為正數(shù)丸冕,所以下一個(gè)任務(wù)的執(zhí)行時(shí)間是相對(duì)上個(gè)任務(wù)的開(kāi)始時(shí)間
- 由于scheduleWithFixedDelay傳入的period為負(fù)數(shù)薛窥,所以下一個(gè)任務(wù)的執(zhí)行時(shí)間是相對(duì)上個(gè)任務(wù)的結(jié)束時(shí)間