2017-08-29 102 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