1. 程式人生 > >DelayQueue的用法介紹

DelayQueue的用法介紹

package com.lyzx.day02;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


/**
 * Throws exception     Special value   Blocks          Times out
 * Insert   add(e)          offer(e)      put(e)          offer(e, time, unit)
 * Remove   remove()        poll()        take()          poll(time, unit)
 *
 *DelayQueue<E extends Delayed>
延遲佇列
 * 這個佇列裡面存放的都是Delayed(介面)
 * Delayed介面繼承了Comparable介面,因為其內部使用PriorityQueue存放元素,所以
 * 需要實現PriorityQueue以排序
 * 
 * DelayQueue取出元素的順序是按照getDelay()的返回的大小
 * 越小的排在越前面
 * 然後按照getDelay()返回的數值N以及單位在當前時間的N個單位後被take()取出
 */
public class T3 {
    public static void main(String[] args){
        DelayQueue<Task>
 queue = new DelayQueue<Task>();
        long now = System.currentTimeMillis();
        System.out.println("now:::::"+now);
        queue.put(new Task("t4",now +4000));
        queue.put(new Task("t1",now +1000));
        queue.put(new Task("t3",now +3000));
        
        ExecutorService es = Executors.newCachedThreadPool();
        //
對DelayQueue遍歷,使用take這個阻塞方法取出延遲時間到了的元素
        //Task也實現了Runnable介面所以當取出這個任務時就可以交給提前準備好的執行緒池
        //去執行這個任務
        while(queue.size() > 0){
            try {
                Task task = queue.take();
                System.out.println("task:"+task);
                es.execute(task);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        es.shutdown();
    }
}

class Task implements Runnable,Delayed{
    private final String name ;
    private final long trigger;
    
    public Task(String name,long tigger){
        this.name=name;
        this.trigger=tigger;
    }
    
    @Override
    public int compareTo(Delayed o) {
        Task target = (Task)o;
        if(this.trigger > target.trigger) return 1;
        if(this.trigger < target.trigger) return -1;
        return 0;
    }
    
    /**
     * 這個方法用於把延遲時間和當前時間的差轉換為對應的時間
     * 至於unit到底是哪一種TimeUnit,不需要使用者知道
     * 注意:如果延遲/觸發時間trigger用毫秒錶示則第一個引數為
     *  trigger-System.currentTimeMillis()
     * 如果trigger用納秒錶示則則第一個引數為
     *  trigger-System.nanoTime()
     */
    @Override
    public long getDelay(TimeUnit unit){
        long r = unit.convert(trigger-System.currentTimeMillis(),TimeUnit.MILLISECONDS);
        return r;
    }

    @Override
    public void run(){
        System.out.println("now:"+System.currentTimeMillis()+"  name:"+name+"   trigger:"+trigger);
    }

    @Override
    public String toString() {
        return "Task [name=" + name + ", trigger=" + trigger + "]";
    }
}