(译)Java Concurrent系列--DelayQueue

来源:互联网 发布:bp神经网络java代码 编辑:程序博客网 时间:2024/05/21 14:45

DelayQueue类实现了BlockingQueue接口,你可以从ArrayBlocking文档里获取更详细的说明。

DelayQueuq内部会阻塞对象元素直到达到指定的延迟(delay)。DelayQueue存放的对象元素必须实现java.util.concurrent.Delayd接口:

public interface Delayed extends Comparable<Delayed< { public long getDelay(TimeUnit timeUnit);//返回给定时间单位情况下对象元素延迟的时间}

getDelay()方法返回的数值代表了对象元素被释放之前需要等待的时间。如果该方法返回0或者一个负值,那么我们认为设置的延迟是无效的,当DelayQueue下一次调用take()等方法时,对象元素立即被取出。

传递给getDelay()方法的TimeUnit实例是一个枚举(Enum),它指定了延迟需要返回的时间类型。TimeUnit枚举的值如下所示:

DAYSHOURSMINUTESSECONDSMILLISECONDSMICROSECONDSNANOSECONDS

Delayed接口继承了java.lan.Comparable接口,这也意味着Delayed对象可以相互进行比较。DelayQueue内部通过compareTo方法来对队列里面的对象元素进行排序,如此一来,DelayQueue可以依据对象的延迟时间来返回对象元素。
下面是一个如何使用DelayQueue的例子:

public class DelayQueueExample {    public static void main(String[] args) {        DelayQueue queue = new DelayQueue();        Delayed element1 = new DelayedElement();        queue.put(element1);        Delayed element2 = queue.take();    }}

总结一下,DelayQueue是一个无界阻塞队列,它里面存放的元素都有一个延迟时间,只有当延迟时间达到后对象元素才能够返回。该队列的头部是达到其延迟时间后停留时间最长的元素,如果所有元素的延迟时间都没有达到,则该队列没有头部,并且poll方法返回null
DelayQueue队列中的对象元素必须实现java.util.concurrent.Delayd接口,并实现compareTogetDelay方法。下面以一个例子作为说明:

import java.util.concurrent.DelayQueue;import java.util.concurrent.Delayed;import java.util.concurrent.TimeUnit;/** * 描述: * 作者:ZP * 创建时间:2017/8/30 * 最后修改时间:2017/8/30 */public class DelayQueueTest {    public static void main(String[] args) {        DelayQueue<DelayElement> queue = new DelayQueue<>();        producer(queue);        consumer(queue);    }    /**     * 消费者,不断从DelayQueue取出DelayElement     * @param queue     */    private static void consumer(DelayQueue<DelayElement> queue) {        new Thread(()->{            while (true) {                DelayElement element = null;                try {                    element = queue.take();                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("Take element from queue: " + element);            }        }).start();    }    /**     * 生产者,每隔100ms生产一个对象     * @param queue     */    private static void producer(DelayQueue<DelayElement> queue) {        new Thread(()->{            while (true) {                try {                    Thread.sleep(100);                } catch (InterruptedException e) {                    e.printStackTrace();                }                DelayElement element = new DelayElement(1000, "test");                queue.put(element);            }        }).start();        //日志线程,每秒打印一次DelayQueue内对象的个数        new Thread(()->{            while (true) {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("queue size is " + queue.size());            }        }).start();    }}class DelayElement implements Delayed{    private final long delay;   //延迟时间    private final long expire;  //过期时间    private final long now;     //创建时间    private final String str;   //信息    public DelayElement(long delay, String str) {        this.delay = delay;        this.str = str;        this.expire = System.currentTimeMillis() + delay;        this.now = System.currentTimeMillis();    }    @Override    public long getDelay(TimeUnit unit) {        return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);    }    @Override    public int compareTo(Delayed o) {        return (int) (this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS));    }    @Override    public String toString() {        return "DelayElement{" +                "delay=" + delay +                ", expire=" + expire +                ", now=" + now +                ", str='" + str + '\'' +                '}';    }}

原文链接
示例代码参考链接

原创粉丝点击