使用DelayQueue实现延时订单的功能

使用DelayQueue来实现延时订单

思路:要使用DelayQueue时,必须要先实现Delayed接口,将数据存入其中,并设置过期时间

当DelayQueue中存有元素时,不一定能立即拿到,必须要先等到过期时间过后,这个时候才可以取到元素,根据这个原理可以来实现延时订单的功能

首先,我们先通过新建一个类并实现该接口

public class ItemVo<T> implements Delayed{
	
	private long activeTime;//到期时间,单位毫秒
	private T date;
	
	//activeTime是个过期时长
	public ItemVo(long activeTime, T date) {
		super();
		this.activeTime = TimeUnit.NANOSECONDS.convert(activeTime, 
				TimeUnit.MILLISECONDS)+System.nanoTime();//将传入的时长转换为超时的时刻
		this.date = date;
	}
	
	public long getActiveTime() {
		return activeTime;
	}

	public T getDate() {
		return date;
	}

	//按照剩余时间排序
	@Override
	public int compareTo(Delayed o) {
		long d = getDelay(TimeUnit.NANOSECONDS)-o.getDelay(TimeUnit.NANOSECONDS);
		return (d==0)?0:((d>0)?1:-1);
	}

	//返回元素的剩余时间
	@Override
	public long getDelay(TimeUnit unit) {
		long d = unit.convert(this.activeTime-System.nanoTime(),
				TimeUnit.NANOSECONDS);
		return d;
	}
	

}

这个时候,我们可以新建一个订单类,存储在ItemVo的属性中

public class Order {
	private final String orderNo;//订单的编号
	private final double orderMoney;//订单的金额
	
	public Order(String orderNo, double orderMoney) {
		super();
		this.orderNo = orderNo;
		this.orderMoney = orderMoney;
	}

	public String getOrderNo() {
		return orderNo;
	}

	public double getOrderMoney() {
		return orderMoney;
	}
	
}

我们的订单类创建完毕了,我们可以使用生产者消费者思想,新建两个类,一个类负责添加订单,一个类负责获取订单(当拿到订单的时候,这个时候说明订单已经过期了)

public class PutOrder implements Runnable {
	
	private DelayQueue<ItemVo<Order>> queue;
	
	public PutOrder(DelayQueue<ItemVo<Order>> queue) {
		super();
		this.queue = queue;
	}

	@Override
	public void run() {
		
		//5秒到期
		Order ordeTb = new Order("Tb12345",366);
		ItemVo<Order> itemTb = new ItemVo<Order>(5000,ordeTb);
		System.out.println(Thread.currentThread().getName()+"  开始加入Tb12345");
		queue.offer(itemTb);
		System.out.println(queue.size());
		System.out.println("订单5秒后到期:"+ordeTb.getOrderNo());
		
		//8秒到期
		Order ordeJd = new Order("Jd54321",366);
		ItemVo<Order> itemJd = new ItemVo<Order>(8000,ordeJd);
		System.out.println(Thread.currentThread().getName()+"  开始加入JD54321");
		queue.offer(itemJd);
		System.out.println(queue.size());
		System.out.println("订单8秒后到期:"+ordeJd.getOrderNo());		
		
	}	
}
public class FetchOrder implements Runnable {
	
	private DelayQueue<ItemVo<Order>> queue;
	
	public FetchOrder(DelayQueue<ItemVo<Order>> queue) {
		super();
		this.queue = queue;
	}	

	@Override
	public void run() {
		while(true) {
			try {
				ItemVo<Order> item = queue.take();
				Order order = (Order)item.getDate();
				System.out.println(Thread.currentThread().getName()+"  get from queue:"+order.getOrderNo());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}	
}

最后,我们新建一个测试类进行测试

public class Test {
    public static void main(String[] args) throws InterruptedException {
    	
    	DelayQueue<ItemVo<Order>> queue = new DelayQueue<>();
    	
    	new Thread(new PutOrder(queue)).start();
    	new Thread(new FetchOrder(queue)).start();

        //每隔500毫秒,打印个数字
        for(int i=1;i<15;i++){
            Thread.sleep(500);
            System.out.println(i*500);
        }
    }
}

好了,我们的延时订单测试成功

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值