JUC定时任务系列之 ScheduledExecutorService
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(); } }