簡體   English   中英

synchronized LinkedList - peek

[英]synchronized LinkedList - peek

LinkedList方便的peekpop ,...方法。

不幸的是,我需要一個線程安全的LinkedList 所以,我的第一個想法是將它包裝如下:

List<Object> list = Collections.synchronizedList(new LinkedList<>());

但是,由於List接口不包含peekpop方法。 這當然不起作用。

或者,我可以在整個代碼中使用synchronized(list)塊。 這是要走的路嗎?

我忽視的任何解決方案?


編輯:

人們使用LinkedList原因有很多。 我看到有些人提出了其他收藏品。 所以,這里遵循簡短的要求,這導致我決定使用LinkedList

更多背景資料:

  • 我正在使用LinkedList,因為需要訂購商品。
  • 應以非阻塞方式添加項目。
  • 物品在后面添加; 從前面移除。
  • 在刪除第一個項目之前,首先需要peek並驗證它。 如果驗證失敗,則該項目需要保留在列表中。
  • 只有驗證成功完成,才會刪除第一個項目。
  • 隊列需要具有最大大小(以避免內存問題)。

如果你需要peek工作,制作同步包裝可能是不夠的,所以你必須明確地寫synchronized

編寫包裝器並不是一個問題,因為它是peek方法的語義問題。 與表示單個動作的pop方法不同, peek方法通常用於由peek -ing組成的多組件動作,然后根據peek返回的內容執行其他操作。

如果在包裝器中進行同步,結果將與手動編寫此代碼時的結果相同:

String s;
synchronized(list) {
    s = list.peek();
}
// <<== Problem ==>>
if (s != null) {
    synchronized(list) {
        s = list.pop();
    }
}

這提出了一個問題,因為有一段時間你的列表可以在peekpop之間進行更改(上面代碼中的這個地方被標記為“Problem”)。

檢查和修改的正確方法是在單個synchronized塊中進行,即

synchronized(list) {
    String s = list.peek();
    if (s != null) {
        s = list.pop();
    }
}

但是,這不能在簡單的包裝器中完成,因為在單個synchronized塊中執行了兩個列表操作。

您可以通過構建自己的封裝LinkedList<T>的數據結構來避免在多個位置進行synchronized編寫,並提供在同步塊中執行所有測試和修改操作的操作。 但是,這不是一個簡單的問題,因此您最好以一種可以使用預定義並發容器之一的方式更改算法。

你想要的是並發Queue LinkedList實現ListDequeQueue Queue是通過peek和pop賦予它FIFO(在后面添加,從前面刪除)語義的原因。

LinkedBlockingQueue可以是有界的,這是您的標准之一。 還有其他幾個並發隊列和Deques可供選擇。

暫無
暫無

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

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