【问题标题】:Polling after a delay in delayed queue延迟队列延迟后轮询
【发布时间】:2014-08-04 06:11:35
【问题描述】:

我有一个示例程序,我试图从中了解延迟队列。我以特定的延迟向队列提供人员对象,当我尝试在 5 秒的间隔后轮询对象时,我应该得到延迟已过期的所有对象。但相反,我得到 null ,我不明白原因。但是当我将延迟设置为 0 时,此轮询有效。有人可以帮我弄清楚我在下面的示例代码中哪里出错了吗?

public class DelayedQueue {
    public static void main(String[] args) {
        BlockingQueue<Person> queue = new DelayQueue<Person>();
        Person a = new Person("ram", "chennai", 1);
        Person b = new Person("nick", "manali", 1);
        Person c = new Person("sam", "delhi", 2);
        try {
            queue.offer(a);
            queue.offer(b);
            queue.offer(c);
            System.out.println(queue.poll(5, TimeUnit.SECONDS));
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
}

class Person implements Delayed {
    private String name;
    private String place;
    private int runningTime;

    public Person(String name, String place, int runningTime) {
        this.name = name;
        this.place = place;
        this.runningTime = runningTime;
    }
    public long getDelay(TimeUnit timeUnit) {           
        return timeUnit.convert(this.runningTime, TimeUnit.MILLISECONDS);

    @Override
    public int compareTo(Delayed person) {
        Person b = (Person)person;   
        return this.name.compareTo(b.name);
    }

    @Override
    public long getDelay(TimeUnit timeUnit) {           
        return timeUnit.convert(this.runningTime, TimeUnit.MILLISECONDS);
    }
}

【问题讨论】:

    标签: java polling blockingqueue


    【解决方案1】:

    你的 getDelay 实现是错误的

    @Override
        public long getDelay(TimeUnit timeUnit) {       
            **// This will never return zero! and the element is never available.**
            return timeUnit.convert(this.runningTime, TimeUnit.MILLISECONDS);
        }
    

    尝试做这样的事情

    @Override
        public long getDelay(TimeUnit timeUnit) {           
            return timeUnit.convert(endOfDelay - System.currentTimeMillis(),
                              TimeUnit.MILLISECONDS);
        }
    

    endOfDelay 设置为 long ( System.currentTimeMillis() + delay (in ms)

    这是您的代码的工作部分:

    public class DelayedQueue
    {
        public static void main(String[] args)
        {
            BlockingQueue<Person> queue = new DelayQueue<Person>();
            Person a = new Person("ram", "chennai", 1);
            Person b = new Person("nick", "manali", 1);
            Person c = new Person("sam", "delhi", 2);
            try
            {
                queue.offer(a);
                queue.offer(b);
                queue.offer(c);
                System.out.println(queue.poll(2, TimeUnit.SECONDS));
            } catch (InterruptedException e1)
            {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
    class Person implements Delayed
    {
        private String name;
        private String place;
        private long delayTime;
    
        public Person(String name, String place, long delayTime)
        {
            this.name = name;
            this.place = place;
            this.delayTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(delayTime);
        }
    
        @Override
        public int compareTo(Delayed person)
        {
            Person b = (Person) person;
            return this.name.compareTo(b.name);
        }
    
        @Override
        public long getDelay(TimeUnit timeUnit)
        {
            return timeUnit.convert(delayTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }
    }
    

    【讨论】:

    • 我在 javadocs 中看到“队列的头部是延迟过期的元素”。但我没有得到使用轮询检索到的最少过期元素。因此,根据上面的程序,当我执行 queue.poll(2, TimeUnit.SECONDS) 时,我无法获得元素 ram 但 nick 并且当我更改延迟时,我总是得到 nick。你能解释一下为什么 poll() 的这种行为是随机的吗?
    • 这是因为您定义了 compareTo。因为它尼克是峰值元素。因此,如果延迟
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 2013-09-27
    • 2015-09-30
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    相关资源
    最近更新 更多