超时订单
序言
电商项目中超时订单的取消,其实是消息超时,该如何处理这一类问题的代表。对于demo类型的定时器扫描表:
- 定时扫描订单信息,找到超时订单
- 修改订单交易状态为取消
- 更新库存
- 返还积分优惠券
以上步骤可能是初学者的练习之作。缺点显然易见存在延时,服务器消耗大。订单很大,数据库的消耗也大。
DelayQueue
无界阻塞队列。用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。
当生产者线程调用
put之类的方法加入元素时,会触发Delayed接口中的compareTo方法进行排序,也就是说队列中元素的顺序是按到期时间排序的,而非它们进入队列的顺序。排在队列头部的元素是最早到期的,越往后到期时间越晚。
消费者线程查看队列头部的元素,注意是查看不是取出。然后调用元素的getDelay方法,如果此方法返回的值小0或者等于0。则消费者线程会从队列中取出此元素,并进行处理。如果getDelay方法返回的值大于0,则消费者线程wait返回的时间(头部元素过期时间),再从队列头部取出元素,此时元素应该已经到期。
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
public class OrderDelay implements Delayed {
private String orderId;
private long timeout;
OrderDelay(String orderId, long timeout) {
this.orderId = orderId;
//超时时间点
this.timeout = timeout + System.nanoTime();
}
@Override
public int compareTo(Delayed other) {
if (other == this)return 0;
OrderDelay t = (OrderDelay) other;
long delay = (getDelay(TimeUnit.NANOSECONDS) - t.getDelay(TimeUnit.NANOSECONDS));
return (delay == 0) ? 0 : ((delay < 0) ? -1 : 1);
}
// 返回距离你自定义的超时时间还有多少
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(timeout - System.nanoTime(),TimeUnit.NANOSECONDS);
}
void print() {
System.out.println(orderId + "编号的订单要删除啦。。。。");
}
}
public class DelayQueueDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
list.add("00000001");
list.add("00000002");
list.add("00000003");
list.add("00000004");
list.add("00000005");
DelayQueue<OrderDelay> queue = new DelayQueue<OrderDelay>();
long start = System.currentTimeMillis();
for (int i = 0; i < 5; i++) { //延迟三秒取出
queue.put(new OrderDelay(list.get(i), TimeUnit.NANOSECONDS.convert(3, TimeUnit.SECONDS)));
try {
queue.take().print();
System.out.println("After " + (System.currentTimeMillis() - start) + " MilliSeconds");
} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
}
}
}
}
本文探讨了电商项目中如何通过Java的DelayQueue技术解决超时订单的取消问题,通过定时扫描、延迟队列操作,避免服务器资源浪费和数据库压力。作者详细介绍了OrderDelay类和DelayQueueDemo的实现,展示了如何使用无界阻塞队列管理订单的取消流程。

741

被折叠的 条评论
为什么被折叠?



