(三)延迟队列DelayQueue实现订单自动取消

DelayQueue:,1)java自带延时获取元素,无界阻塞队列,2)队列内部用PriorityQueue实现。     创建元素时可指定多久才能从队列中获取当前元素。期满才从队列中提取,没到延时时间,阻塞当前线程。

泛型队列,继承Delayed,需重写getDelay和compareTo方法。

1.public class DelayQueueextends Delayed>extends AbstractQueue

2.public int compareTo(T o); 往DelayQueue加入数据执行,根据返回值判断位置。排得越前,越先被消费

3. long getDelay(TimeUnit unit);判断消息是否到期。负数,已到期,可读。

优点:java自带,轻量级,使用简单

缺点:存储内存中,服务器重启会造成数据丢失,配合redis使用。数量大用mq

订单类,实现Delayed接口

(三)延迟队列DelayQueue实现订单自动取消_第1张图片
(三)延迟队列DelayQueue实现订单自动取消_第2张图片

unit.convert(this.createdTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()+expireTime-System.currentTimeMillis(),TimeUnit.MILLISECONDS);

(三)延迟队列DelayQueue实现订单自动取消_第3张图片
(三)延迟队列DelayQueue实现订单自动取消_第4张图片
System.out.println(String.format("时间:%s,订单:%s加入队列", order.getCreatedTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), order.getOrderNo()));
(三)延迟队列DelayQueue实现订单自动取消_第5张图片
(三)延迟队列DelayQueue实现订单自动取消_第6张图片

数据量小推荐使用:DelayQueue+redis

DelayQueue分布式环境中就会重复执行;所以加redis:

每次生成订单时,同时向 redis setnx 设定该未支付订单,

每次查询待支付订单时须从 redis 中也查一遍,

redis 不存在该订单,改为已取消。

数据量大推荐使用:RabbitMQ

AB 两个队列,A 队列设置消息过期时间没有消费者,A 过期自动转发到 B ,B 队列消费者取消

https://www.jianshu.com/p/2ef8646fe8f7

https://www.v2ex.com/amp/t/407801

你可能感兴趣的:((三)延迟队列DelayQueue实现订单自动取消)