刚刚好点进去看了,做个笔记
先读
这样子的延迟任务代码很常见,在保持心跳、延迟确认等等场景
从源码的角度看他是怎么实现的
@Test
public void delayTest() throws InterruptedException {
Executors.newScheduledThreadPool(1).schedule(() -> {
System.out.println("一秒后执行任务");
},1,TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(111);
}
分析
投递阻塞队列,创建工作线程不断获取任务
问题点
- 不断的轮询效率会很差(因为要实时校验时间到了没)
- 不能保证时间顺序(可能后投递的要先执行,顺序乱了)
特殊实现
问题点一
轮询的效率当然很差,但是java有wait呀
具体代码:java.util.concurrent.ScheduledThreadPoolExecutor.DelayedWorkQueue#take
使用AQS实现的锁(LockSupport)
问题点二
对于添加顺序: 重写BlockingQueue的offer方法
下图:每次添加的时根据时间排序队列
下图: 在类内部重写的BlockingQueue