2017-08-29 64 views
0

我正在实施生产者/消费者模式并使用LinkedTransferQueue集合。如何限制LinkedTransferQueue的大小?

我不希望我的制作者超出某些内存限制。

目前我正在使用此检查,但从documentation开始,大小操作需要O(N)遍历。对于我目前的实现中,它是好的,

但没有任何比一个更好的办法,我目前使用 ?

LinkedTransferQueue<String> producerStringLinkedTransferQueue = new LinkedTransferQueue<String>(); 

if (producerStringLinkedTransferQueue.size() <= 5000) { 
    producerStringLinkedTransferQueue.add(<some data>); 
} 
+0

这当然不是这样做的。 [“确定当前元素数量...如果在遍历过程中修改了此集合,则可能会报告不准确的结果。”](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ LinkedTransferQueue.html) – Michael

+0

同意:),因为我不必对尺寸验证非常严格,我使用这种方法,但不应该使用它,如果尺寸验证非常严格 –

回答

1

如果你想要做什么,当队列已满(不是取代它的最古老的项目,例如,Apache的公共集合CircularFifoQueue一样),那么你可以用你的自定义类LinkedTransferQueue和实施都需要的方法计算队列大小:

public class LimitLinkedTransferQueue<E> { 
    LinkedTransferQueue<E> queue = new LinkedTransferQueue<>(); 
    private final long maxSize; 
    private long size = 0; 

    public LimitLinkedTransferQueue(long maxSize) { 
     super(); 
     this.maxSize = maxSize; 
    } 

    public boolean add(E e) { 
     if (this.size == this.maxSize){ 
      return false; 
     } 
     boolean result = queue.add(e); 
     if (result) { 
      size++; 
     } 
     return result; 
    } 

    public E take() throws InterruptedException { 
     E item = queue.take(); 
     size--; 
     return item; 
    } 
    // other need methods 
} 
+0

非常好的解决方案。这将是值得实施一些接口,如'Iterable'。您可以(也应该)通过删除“Integer.MAX_VALUE”来使'maxSize'最终。它也不是线程安全的 - LinkedTransferQueue是一个并发集合,所以我希望有限的一个线程安全。 – Michael

+1

是的,你是对的。我已经编辑了'maxSize'的答案,并且还需要改进线程安全的代码。 – Nikolay