DelayQueue 阻塞队列

DelayQueue是什么?

DelayQueue是一个无界的BlockingQueue(阻塞队列),用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。

注意:不能将null元素放置到这种队列中。

DelayQueue能做什么?

1. 淘宝订单业务:下单之后如果三十分钟之内没有付款就自动取消订单。

2. 饿了吗订餐通知:下单成功后60s之后给用户发送短信通知。

3.关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之。

4.缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出。

5.任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求等。 

注意

DelayQueue  没有持久化,重启服务器后消息会丢失。看业务需求使用。

代码片段

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Executors;
import javax.annotation.PostConstruct;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.cxtrip.utils.LogUtils;
import com.cxtrip.utils.NullUtils;
import com.cxtrip.utils.ServiceNoticeUtil;

@Component
@Lazy(false)
public class DelayOrderComponent{
   
    private static DelayQueue<OrderMessage> delayQueue = new DelayQueue<OrderMessage>();
    
    @PostConstruct
    public void init() throws Exception {
        /**启动单线程池,去取延迟消息**/
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                OrderMessage message = null;
                // 不断的获取队列消息(只有到期的数据才会被取出来)
                while (true) {
                    try {
                        // 取出队列消息
                        message = delayQueue.take(); 
                        // 业务逻辑-------------
        
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    
    /**加入延迟消息队列**/
    public static boolean addOrderDelayQueue(OrderMessage orderMessage){
        return delayQueue.add(orderMessage);
    }
}

Delayed对象

import java.util.Date;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import com.cxtrip.utils.DateUtils;

public class OrderMessage implements Delayed {
    
    private final String orderId;//序号
    
    private final long startTime ;//开始时间

    private final long expire ;//到期时间
    
    private final Date now; //创建时间
    
    private final String orderMsg;//其他信息JSON方式保存,备用字段,可存储对象字段(对象转JSON)
    
    // secondsDelay 延迟多少秒
    public OrderMessage(String orderId, String startTimeStr, String orderMsg ,long secondsDelay) {
        super();
        this.orderId = orderId;
        this.startTime = DateUtils.date2Time(startTimeStr, "yyyyMMddHHmmss");
        this.expire = startTime + (secondsDelay*1000);
        this.orderMsg = orderMsg;
        this.now = new Date();
    }

    @Override
    public int compareTo(Delayed o) {
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) -o.getDelay(TimeUnit.MILLISECONDS));
    }

    //只有到期的数据才会被取出来
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(this.expire - System.currentTimeMillis() , TimeUnit.MILLISECONDS);
    }

    public String getOrderId() {
        return orderId;
    }

    public String getOrderMsg() {
        return orderMsg;
    }
    
    public Date getNow() {
        return now;
    }

    public long getStartTime() {
        return startTime;
    }

    public long getExpire() {
        return expire;
    }

} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值