定时轮询
数据库定时轮询方式,实现思路比较简单。启动一个定时任务,每隔一定时间扫描订单表,查询到超时订单就取消。
优点:实现简单。
缺点:轮询时间间隔不好确定,占用服务器资源,影响数据库性能。
惰性取消
当查询订单信息时,先判断该订单是否超时,如果超时就先取消。
优点:实现简单。
缺点:影响查询之外的业务(如:统计、库存),影响查询效率。
JDK延迟队列
JDK延时队列DelayQueue是一个无界阻塞队列,该队列只有在延迟期满的时候才能从中获取元素。
简单实现代码demo如下,实际生产过程中会有专门的线程负责消息的入队与消费。
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* @author 向振华
* @date 2022/08/16 15:55
*/
public class OrderDelayed implements Delayed {
/**
* 延迟时间
*/
private final Long time;
/**
* 订单编号
*/
public String orderNo;
public OrderDelayed(String orderNo, long time, TimeUnit unit) {
this.orderNo = orderNo;
this.time = System.currentTimeMillis() + (time > 0 ? unit.toMillis(time) : 0);
}
@Override
public long getDelay(TimeUnit unit) {
return time - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed o) {
OrderDelayed orderDelayed = (OrderDelayed) o;
long diff = this.time - orderDelayed.time;
if (diff <= 0) {
return -1;
} else {
return 1;
}
}
}
import java.util.concurrent.DelayQueue;
import java.util.concurrent.TimeUnit;
/**
* @author 向振华
* @date 2022/08/16 16:02
*/
public class Test {
public static void main(String[] args) {
DelayQueue<OrderDelayed> delayQueue = new DelayQueue<>();
delayQueue.put(new OrderDelayed("220101001", 8, TimeUnit.SECONDS));
delayQueue.put(new OrderDelayed("220101002", 4, TimeUnit.SECON