前言
我们使用Java实现周期任务或者延时任务,一般都会采用ScheduledThreadPoolExecutor来实现。而翻看了源码以后发现,周期任务和延时任务实现的核心就是一个特殊的阻塞队列 — DelayedWorkQueue
为什么要自定义一个阻塞队列?
ThreadPoolExecutor中,每一个线程都被封装成一个Worker对象,通过Worker对象中的getTask()方法不断拉取任务执行。
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
// ... 调用task的run方法
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
从以上代码看出,getTask()取出来后会立刻调用run方法,因此没法做到延迟或周期效果。所以ScheduledThreadPoolExecutor自定义了一个队列以实现功能。
ScheduledFutureTask
实现周期任务通常调用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