超时订单取消

本文探讨了电商项目中如何通过Java的DelayQueue技术解决超时订单的取消问题,通过定时扫描、延迟队列操作,避免服务器资源浪费和数据库压力。作者详细介绍了OrderDelay类和DelayQueueDemo的实现,展示了如何使用无界阻塞队列管理订单的取消流程。
摘要由CSDN通过智能技术生成

超时订单

序言

电商项目中超时订单的取消,其实是消息超时,该如何处理这一类问题的代表。对于demo类型的定时器扫描表:

  1. 定时扫描订单信息,找到超时订单
  2. 修改订单交易状态为取消
  3. 更新库存
  4. 返还积分优惠券

以上步骤可能是初学者的练习之作。缺点显然易见存在延时,服务器消耗大。订单很大,数据库的消耗也大。

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();              }          }      }   }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值