一、Timer解析
TaskQueue:小顶堆,存放timeTask。
TimerThread:任务执行线程
- 死循环不断检查是否有任务需要开始执行,有就执行它。
- 始终是一个线程在执行。
单线程执行任务,任务有可能相互阻塞:
- schedule:任务执行超时,会导致后面的任务往后推移,预想在这个间隔内存在的任务执行就没有了。
- scheduleAtFixedRate:任务超时可能导致下一个任务就会马上执行。
运行时异常会导致timer线程终止。
任务调度是基于绝对时间的,对系统时间敏感。
二、定时任务线程池
ScheduledThreadPoolExecutor
- 使用多线程执行任务,不会相互阻塞。
- 如果线程失活,会新建线程执行任务:线程抛异常,任务会被丢弃、需要做捕获处理。
- DelayedWorkQueue:小顶堆,无界队列:
- 在定时线程池中,最大线程数是没有意义的。
- 执行时间距离当前时间越接近的任务在队列的前面。
- 用于添加ScheduleFutureTask(继承于FutureTask,实现RunnableScheduledFuture接口):提供异步执行能力,并且可以返回执行结果。
- 线程池中的线程从DelayQueue中获取ScheduleFutureTask, 然后执行。
- 实现了Delayed接口,可以通过getDelay方法来获取延迟时间。
- Leader - Follower模式:避免没必要的唤醒和阻塞的操作,这样会更加有效,且节省资源。
- 应用场景:适用于多个后台线程执行周期任务,同时为了满足资源管理的需求需要限制后台线程数。
SingleThreadScheduledExecutor
- 单线程的ScheduledThreadPoolExecutor
- 应用场景:适用于需要单个后台线程执行周期任务,同时需要保证任务顺序执行。