前言
进入阅读了一下定期线程池源码,感觉还是不错的。简历就是把前2天的项目给封装到简历上去了。
1.ScheduledExecutorService
首先看他的2个核心方法
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
//4个参数 command任务 initialDelay第一次执行需要延时嘛 period每个任务的延时时间
//`scheduleAtFixedRate` 方法:该方法按照固定的时间间隔执行任务,无论上一次任务是否完成。
//`scheduleWithFixedDelay` 方法:该方法在上一次任务完成后,等待固定的时间间隔后再执行下一次任务。
源码阅读 scheduleWithFixedDelay方法
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;
}
delayedExecute方法
private void delayedExecute(RunnableScheduledFuture<?> task) {
//判断线程池状态是否关闭
if (isShutdown())
//拒绝策略
reject(task);
else {
//当前任务入队
super.getQueue().add(task);
//判断线程池状态
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
else
//关键
ensurePrestart();
}
}
void ensurePrestart() {
//这个之前说过了 拿到工作线程数量
int wc = workerCountOf(ctl.get());
//看是否超过核心线程
if (wc < corePoolSize)
//创建一个工作线程
addWorker(null, true);
else if (wc == 0)
//创建一个工作线程
addWorker(null, false);
}
addWorker方法没什么好看的吧 他不是加入队列了吗就看Worker队列拿出来之后干了什么就知道了呗ScheduledFutureTask的run方法就行今天就这把后面具体代码不是很懂啊