延时队列DelayQueue

DelayQueue是一个无界的BlockingQueue(线程安全),用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。通俗地讲,延时队列是指在某个时间点延迟一段时间执行。(延时队列也是队列的一种,遵循先进先出的特点)

要将延时队列和定时任务区分开!!!

定时任务:在特定时间执行任务。

应用场景

  • 缓存:

存储在缓存中的对象,超过空闲时间,需要从缓存中移除。

  • 支付场景:

提交订单后限定时间内若没有付款就自动取消订单。

  • 任务超时处理:

处理超时未响应的请求等。

  • 空闲连接的关闭:

服务器中,有很多客户端的连接,空闲一段时间之后需要关闭。

延时队列实现

  • 简单:Java原生的延迟队列

JDK 中提供了一组实现延迟队列的API,位于java.util.concurrent包下DelayQueue。

本质就是封装了一个PriorityQueue(优先队列),内部使用完全二叉树来实现队列元素排序。

向DelayQueue队列中添加元素时,会给元素一个Delay(延迟时间)作为排序条件,队列中最小的元素会优先放在队首。队列中的元素只有到了Delay时间才允许从队列中取出。

队列中可以放基本数据类型或自定义实体类,在存放基本数据类型时,优先队列中元素默认升序排列,自定义实体类就需要我们根据类属性值比较计算了

优点:系统不需要和其他服务进行数据通讯,所有的请求都在项目内容进行,避免了两个服务之间因为信道不稳定导致数据丢失的情况。

缺点:一旦服务器重启就会导致数据丢失。( 但如果延时发送的消息重要性并不是很高那影响就不大)

  • 复杂:借助其他中间件

1. redis

redis——> 轮询。Java程序开辟一个线程去轮询这个redis,不断地去看这个key有没有过期。

redis——> 过期回调(redis的key过期以后,可以通知到我的服务器),写一个监听类一般不建议使用

2. RabbitMQ延时队列

通过RabbitMQ消息队列的TTL(Time To Live存活时间)设置消息的存活时间。

可以从两种维度设置消息过期时间,分别是队列和消息本身:

  • 设置队列过期时间,那么队列中所有消息都具有相同的过期时间。

  • 设置消息过期时间,对队列中的某一条消息设置过期时间,每条消息TTL都可以不同。

优点:消息可靠性高。

缺点:需要额外配置TTL并且可能存在消息堆积或者延迟不准确的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值