簡體   English   中英

Java為高並發情況限制了非阻塞緩沖區

[英]Java bounded non-blocking buffer for high concurrent situation

基本上我需要一個數據結構來存儲服務器端的臨時聊天消息。 它應該是:

  • 有界:因為我不需要存儲太多消息,客戶端將發送請求以每秒獲取新消息。 我認為綁定大小應該是最大值。 在一秒鍾內掛載並發請求。 當緩沖區已滿時,將刪除舊消息。

  • 適合高並發訪問:我不想使用像Collections.synchronizedXXXX這樣的數據結構,因為在迭代期間,如果其他線程更改了數據結構,例如添加了一條消息,它將拋出異常,所以我必須鎖定整個數據結構,實際上我並不關心客戶端請求是否可以獲得最后插入的消息,因為它們將在一秒鍾后發送新請求,另一方面寫操作應該永遠不會延遲。 包java.util.concurrency下的類似乎是解決方案,但是......

  • 非阻塞:LinkedBlockingQueue,ArrayBlockingQueue它們可以有界並且在迭代期間不會拋出異常,但它們都是阻塞隊列。 當隊列已滿時,我想將新元素添加到尾部並從頭部刪除舊元素而不是阻塞它並等待某人刪除標題。

所以我的問題是第三個庫有什么好的實現嗎? 比如谷歌番石榴? 或者您可能更了解在服務器上存儲臨時聊天消息?

非常感謝你!

您可以使用Apache Commons CircularFifoBuffer 它符合您的第一個和最后一個標准。 要支持並發,可以將基本緩沖區包裝在其同步版本中,如下所示:

Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());

祝這個項目好運。

您可以使用LinkedBlockingQueue和非阻塞方法offer (或add )和poll來訪問它。 您可以使用固定容量創建它以使其有界。

LinkedBlockingQueue<String> myStrings = new LinkedBlockingQueue<String>(100);
myStrings.offer("Hi!"); // returns false if limit is reached
myStrings.add("Hi, again!"); // throws exception if limit is reached
String s = myStrings.poll(); // returns null if queue is empty

你看過ConcurrentLinkedQueue了嗎? 該頁面說

該實現采用有效的“等待”算法......

等待自由是你獲得的最強保證之一....

您可以通過使用條件offer()語句將其附加到ArrayBlockingQueue來添加非阻塞行為,其中接受該報價的隊列失敗會導致磁頭被刪除並且重新提供要約:

    public class LearnToQueue {


    public static void main(String[] args){
        Queue<Integer> FIFO = new ArrayBlockingQueue<Integer>(4);

        int i = 0;

        while ( i < 10 ){

            if (!FIFO.offer(i)){
            // You can pipe the head of the queue anywhere you want to
                FIFO.remove();
                FIFO.offer(i);
            }
            System.out.println(FIFO.toString());
            i++;

        }
    }

    }

LinkedTransferQueue是一個阻塞的無界隊列,不強制執行嚴格的FIFO排序。 它只會在從空隊列中獲取時阻止,但從不添加到一個隊列。 你可以通過添加一個大小或讀寫計數器來添加一個軟帽來驅逐元素。

根據您的要求,您可以編寫自定義無鎖環緩沖區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM