你真的了解延时队列吗(一)
特点:定期轮训数据库,设置状态。
优点:实现简单 缺点:数据量过大时会消耗太多的IO资源,效率太低2.2 DelayQueue
特点: 无界、延迟、阻塞队列
a、BlockingQueue+PriorityQueue(堆排序)+Delayed b、DelayQueue中存放的对象需要实现compareTo()方法和getDelay()方法。 c、getDelay方法返回该元素距离失效还剩余的时间,当 =0时元素就失效了, 就可以从队列中获取到。
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_61129777b3b66.png)
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_61129778437a3.png)
这里为什么要用leader/follower模式?
如果不是队首节点,根本不需要唤醒操作! 假设取值时,延时时间还没有到,那么需要等待,但这个时候,队列中新加入了一个延时更短的,并放在了队首,那么 此时,for循环由开始了,取得是新加入的元素,那之前的等待就白等了,明显可以早点退出等待! 还有就是如果好多线程都在此等待,如果时间到了,同时好多线程会充等待队列进入锁池中,去竞争锁资源,但结果只能是一个成功, 多了写无畏的竞争!(多次的等待和唤醒)
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_61129778dc662.png)
2.3 Timer与TimerTask
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_61129779298d7.png)
时间格:环形结构中用于存放延迟任务的区块; 指针(CurrentTime):指向当前操作的时间格,代表当前时间 格数(ticksPerWheel):为时间轮中时间格的个数 间隔(tickDuration):每个时间格之间的间隔 总间隔(interval):当前时间轮总间隔,也就是等于ticksPerWheel*tickDuration
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_6112977a85ac3.png)
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_6112977acdf6a.png)
根据每个TimerTaskEntry的过期时间和当前时间轮的时间,选择一个合适的bucket(实际上就是TimerTaskList),把这个TimerTaskEntry对象放进去,同时如果bucket的过期时间有更新,就将这个bucket推进DelayQueue,重新排序
例子:假设编号为0的时间格或者桶保存着到期时间为t,每一个tick的持续时间(tickDuration)为20ms,在这个格子里只能保存着到期时间为[t~t+20]ms的任务,假设时间轮的时间格有n个,每一个间隔1ms,到期时间为m(ms),那么计算公式m%n = 所在的时间格或者桶,比如n=10,m=34ms,那么他所在桶或者时间格是4
2.5 RabbitMQ-延时任务RabbitMQ本身没有直接支持延迟队列功能,但是可以通过以下特性模拟出延迟队列的功能。
RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter RabbitMQ针对队列中的消息过期时间有两种方法可以设置。 A: 通过队列属性设置,队列中所有消息都有相同的过期时间。 B: 对消息进行单独设置,每条消息TTL可以不同。
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_6112977b5da76.png)
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_6112977bb47b0.png)
为什么不用Timer?
Timers没有持久化机制. Timers不灵活 (只可以设置开始时间和重复间隔,不是基于时间、日期、天等(秒、分、时)的) Timers 不能利用线程池,一个timer一个线程 Timers没有真正的管理计划
三者关系:调度器负责调度各个任务,到了某个时刻或者过了一定时间,触发器触动了,特定任务便启动执行。
![你真的了解延时队列吗(一)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/08/10/20210810_6112977c2e7b1.png)
待续。。。
作者:公众号_咖啡拿铁
链接:https://juejin.im/post/5b5a0bf9f265da0f6523913b
来源:掘金
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/62235.html
aliyun阿里