JDK自带的调度有远古时代的Timer 和Task
JUC包的ScheduledExecutorService 本节重点研究ScheduledExecutorService;
代码示例如下:
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println("开始调度了");
} catch (Throwable ignored) {
}
}
};
scheduledExecutorService.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
}
关于线程池相关的 重点参数有 :
corePoolSize :核心线程数 maximumPoolSize:最大线程数
keepAliveTime 当线程池数量超过 核心线程数之后,决定线程等待新任务的最大等待时间
TimeUnit:最大等待时间的单位
BlockingQueue<Runnable> workQueue:此用延迟队列
ThreadFactory threadFactory:线程工厂类 一般定义一下线程的名字 等
RejectedExecutionHandler handler:拒绝策略 常见的有以下几种:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
开始主核心逻辑解析:
scheduledExecutorService.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.MINUTES);
代码不多直接贴上:
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit) {
//1.参数检查
if (command == null || unit == null)
throw new NullPointerException();
if (period <= 0)
throw new IllegalArgumentException();
//2.根据延迟时间,和执行周期创建 ScheduledFutureTask 对象
ScheduledFutureTask<Void> sft =
new ScheduledFutureTask<Void>(command,
null,
triggerTime(initialDelay, unit),
unit.toNanos(period));
//3.装饰
RunnableScheduledFuture<Void> t = decorateTask(command, sft);
sft.outerTask = t;
delayedExecute(t);
return t;
}
类的结构:
ScheduledFutureTask继承了 FutureTask 实现了 RunnableScheduledFuture
private void delayedExecute(RunnableScheduledFuture<?> task) {
if (isShutdown())
reject(task);
else {
//1.任务加入延迟队列
super.getQueue().add(task);
if (isShutdown() &&
!canRunInCurrentRunState(task.isPeriodic()) &&
remove(task))
task.cancel(false);
else
//启动任务执行
ensurePrestart();
}
}