我在使用延迟队列。我需要使用这个,以便只有在经过延迟时才从队列中取出。我还想强制执行一个容量,很像阻塞队列。我好像找不到这个的集合实现。有一个存在吗?如果没有,最好的方法是什么?一个基本的方法是这样做:

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

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

    queue.add(somethingToAdd);
}

这意味着每次删除某个内容时都会调用notify/notifyall。这是一个相当小的班级,所以这是可行的。听起来不太好。我不确定等待/通知是否会导致进一步的问题?
对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将在同步块中阻塞,并且对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;
    }
}

10-02 23:15