java - 有容量的延迟队列

标签 java collections concurrency

我正在使用延迟队列。我需要使用它以便仅在延迟过去后才从队列中取出。我还想强制执行一个容量,很像 BlockingQueue。我似乎找不到这个的 Collections 实现。一个存在吗?如果没有,实现它的最佳方式是什么?一个基本的方法是做这样的事情:

public void addSomethingToQueue(Object somethingToAdd){
    int capacity = 4;

    while(queue.size() >= capacity){
        try{
            wait();
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }

    queue.add(somethingToAdd);
}

这意味着每次删除某些内容时都会调用 notify/notifyAll。这是一个很小的类(class),所以这是可行的。虽然听起来不太好。而且我不确定等待/通知是否会导致进一步的问题?

子类化 DelayQueue 并乱用它的方法会更好吗?感觉有点狡猾...

最佳答案

为什么不组合一个 BlockingQueue 和一个 DelayQueue?例如:

class MyDelayBlockingQueue<T> implements Queue {
    private final DelayQueue<T> delayQ = ...
    private final BlockingQueue<T> blockingQ = ...

    public synchronized void offer(T obj) {
        blockingQ.offer(obj); // this will block if the Q is full
        delayQ.offer(obj);
    }

    public synchronized T poll() {
        T obj = delayQ.poll(); // This will handle the delay
        if (obj != null) {
            blockingQ.poll();
        }
        return obj;
    }

    // ...    
}

编辑

上面的代码会死锁。如果 Q 已满,offer 将阻塞在一个同步块(synchronized block)中,并且以后所有对 poll 的调用都将阻塞以获取 Q 的内在锁 - 从而导致死锁。尝试类似的东西:

public class DelayBlockingQueue<E extends Delayed>
{
    private final DelayQueue<E> delayQ = new DelayQueue<E>();
    private final Semaphore available;

    public DelayBlockingQueue(int capacity)
    {
        available = new Semaphore(capacity, true);
    }

    public void offer(E e) throws InterruptedException
    {
        available.acquire();
        delayQ.offer(e);
    }

    public E poll()
    {
        E e = delayQ.poll();
        if (e != null)
        {
            available.release();
        }
        return e;
    }
}

关于java - 有容量的延迟队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6746604/

相关文章:

java - 可以按值的顺序迭代的映射

c# - 从 App.config 文件读取集合

java - 如何从 J2EE Web 应用程序中的服务层调用 DAO 方法

java - 从哪里可以获得 Notes.jar 或 NCSO.jar?

java - 我需要一个基本的简单Java布局方法

java - 为什么 iterator.hasNext 不适用于 BlockingQueue?

android - 一项并发服务或多项服务

java - 从静态类接收数据

使用枚举、方法和用户输入更新的 Java Suit 应用程序

java - java中使用多线程下载