DelayQueue实现延迟订单,代码逻辑实现好了。下面分享哈他是怎样实现得

一个基本得延迟订单功能做好了,在Test.java里面有测试用例,可以自己扩展更为高效得延迟订单,比如说加入消息队列什么的。下面是链接:

https://pan.baidu.com/s/1HLMeW-EIEqlKA9SDn9ffDw   密码:6t84

下面我们看好着DelayQueue大概是怎样得

put订单得时候,我们会调用offer()方法,offer()方法如下:

public boolean offer(E e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        //q  PriorityQueue优先级队列,实际上是一个堆(不指定Comparator时默认为最小堆)TOP K问题就可以使用它
        q.offer(e);  //入队
        if (q.peek() == e) {
            leader = null;  //q.peek() == e 时将leader线程置为空
            //调用Condition的signal()方法将会唤醒再等待队列中的首节点,该节点也是到目前为止等待时间最长的节点
            available.signal();
        }
        return true;
    } finally {
        lock.unlock();
    }
}

取订单时,使用take(),并且得开线程执行,take方法如下:

public E take() throws InterruptedException {
     //lock锁
    final ReentrantLock lock = this.lock;
    //这个会先判断当前线程是否被中断,然后抛出异常。而使用lock.lock()时,调用interrupt(),也不会抛出异常,一直去获取锁cas
    lock.lockInterruptibly();
    try {
        for (;;) {  //这个就不用多说了
            E first = q.peek();
            if (first == null)
                available.await(); //为空等待
            else {
                long delay = first.getDelay(NANOSECONDS);
                if (delay <= 0)
                    return q.poll();  //过期了出队  ,先进先出
                first = null; // don't retain ref while waiting
                if (leader != null)
                    //等待队列中还剩余未过期订单,
                    available.await();
                else {
                     //take 的线程  这个因为我们take的时候,是在一个线程里while(true){take()}
                     //因为是只开了一个线程来无限take(),如果存在多个线程一起来take()的时候,leader就有可能失去领导地位
                    Thread thisThread = Thread.currentThread();
                    leader = thisThread;
                    try {
                         //轮询检查线程是否在同步线程上,如果在则退出自旋。否则检查是否已超过解除挂起时间,如果超过,则退出挂起,否则继续挂起线程到等待解除挂起
                        available.awaitNanos(delay);
                    } finally {
                        if (leader == thisThread)
                            leader = null;
                    }
                }
            }
        }
    } finally {
        if (leader == null && q.peek() != null)
            available.signal();
        lock.unlock();
    }
}

到此结束吧,有兴趣的伙伴,可以想哈为什么使用leader???有什么作用???

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值