1. 程式人生 > >延遲佇列DelayQueue簡單入門

延遲佇列DelayQueue簡單入門

一、DelayQueue是什麼

DelayQueue是一個無界的BlockingQueue,用於放置實現了Delayed介面的物件,其中的物件只能在其到期時才能從佇列中取走。這種佇列是有序的,即隊頭物件的延遲到期時間最長。注意:不能將null元素放置到這種佇列中。

二、DelayQueue能做什麼

1. 淘寶訂單業務:下單之後如果三十分鐘之內沒有付款就自動取消訂單。 
2. 餓了嗎訂餐通知:下單成功後60s之後給使用者傳送簡訊通知。

三、實際開發中的應用

簡單的延時佇列要有三部分:第一實現了Delayed介面的訊息體、第二消費訊息的消費者、第三存放訊息的延時佇列
1.訊息體。實現介面 Delayed ,重寫方法 compareTo 和 getDelay

public class Message implements Delayed{

    private Map<String,String> body=new HashMap<>();  //訊息內容
    private long excuteTime;//執行時間
    private String type;

    public Map<String, String> getBody() {
        return body;
    }
    public void setBody(Map<String, String> body) {
        this.body = body;
    }
    public long getExcuteTime() {
        return excuteTime;
    }
    public void setExcuteTime(long excuteTime) {
        this.excuteTime = excuteTime;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public Message(long delayTime,String type) {
        this.excuteTime = TimeUnit.NANOSECONDS.convert(delayTime, TimeUnit.MILLISECONDS) + System.nanoTime();
        this.type=type;
    }
    @Override
    public int compareTo(Delayed delayed) {
        long d = (getDelay(TimeUnit.NANOSECONDS) - delayed.getDelay(TimeUnit.NANOSECONDS));
        return (d == 0) ? 0 : ((d < 0) ? -1 : 1);
    }
    @Override
    public long getDelay(TimeUnit unit) {
        return  unit.convert(this.excuteTime - System.nanoTime(), TimeUnit.NANOSECONDS);
    }
}

2.宣告消費者。實現介面Runnable

public class Consumer implements Runnable {

    // 延時佇列
    private DelayQueue<Message> queue;
    public static boolean  isRun=false;

    public Consumer(DelayQueue<Message> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        isRun=true;
        while (true) {
            try {
                Message take = queue.take();
                System.out.println("訊息型別:" + take.getType());
                Map<String,String> map=take.getBody();
                System.out.println("訊息內容:");
                for (String key:map.keySet()){
                    System.out.println("key="+map.get(key));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

3.延遲佇列管理者,用於在任何地方獲取 DelayQueue 

public class DelayQueueManager {

    private static DelayQueue<Message> delayQueue=null;

    static {
        // 建立延時佇列
       delayQueue = new DelayQueue<Message>();
    }

    public static DelayQueue<Message> getDelayQueue(){
        return delayQueue;
    }
}

4.使用延遲佇列傳送訊息

 // 新增延時訊息,m1 延時5s
	Message m1 = new Message( 5000,"訂單");
	m1.getBody().put("content","12345");
	// 新增延時訊息,m1 延時5s
	DelayQueueManager.getDelayQueue().offer(m1);
	if(!Consumer.isRun){
		// 啟動消費執行緒
		new Thread(new Consumer(DelayQueueManager.getDelayQueue())).start();
	}

以上就是延遲佇列delayQueue的簡單入門配置和使用,希望對你有幫助!

文章參考:
https://blog.csdn.net/zhu_tianwei/article/details/53549653