DelayQueue с емкостью - PullRequest
       4

DelayQueue с емкостью

3 голосов
/ 19 июля 2011

Я использую DelayQueue. Мне нужно использовать это, чтобы брать из очереди только после того, как задержка прошла. Я также хочу усилить емкость, очень похожую на BlockingQueue. Я не могу найти реализацию коллекций этого. Один существует? Если нет, каков наилучший способ его реализации? Основным подходом было бы сделать что-то вроде этого:

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 и возиться с его методами? Чувствуется немного хитро ...

Ответы [ 2 ]

1 голос
/ 19 июля 2011

Почему бы не составить 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;
    }

    // ...    
}

EDIT

Код выше заблокирует. Если Q заполнен, предложение будет блокироваться в синхронизированном блоке, и все будущие вызовы 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;
    }
}
0 голосов
/ 19 июля 2011

Вы можете использовать LRU: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used

Пример реализации от Apache Commons: http://commons.apache.org/collections/api/org/apache/commons/collections/LRUMap.html

Так что вы больше не пишете; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...