[英]synchronized LinkedList - peek
LinkedList
有方便的peek
, pop
,...方法。
不幸的是,我需要一個線程安全的LinkedList
。 所以,我的第一個想法是將它包裝如下:
List<Object> list = Collections.synchronizedList(new LinkedList<>());
但是,由於List
接口不包含peek
或pop
方法。 這當然不起作用。
或者,我可以在整個代碼中使用synchronized(list)
塊。 這是要走的路嗎?
我忽視的任何解決方案?
編輯:
人們使用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();
}
}
這提出了一個問題,因為有一段時間你的列表可以在peek
和pop
之間進行更改(上面代碼中的這個地方被標記為“Problem”)。
檢查和修改的正確方法是在單個synchronized
塊中進行,即
synchronized(list) {
String s = list.peek();
if (s != null) {
s = list.pop();
}
}
但是,這不能在簡單的包裝器中完成,因為在單個synchronized
塊中執行了兩個列表操作。
您可以通過構建自己的封裝LinkedList<T>
的數據結構來避免在多個位置進行synchronized
編寫,並提供在同步塊中執行所有測試和修改操作的操作。 但是,這不是一個簡單的問題,因此您最好以一種可以使用預定義並發容器之一的方式更改算法。
你想要的是並發Queue
。 LinkedList
實現List
, Deque
和Queue
。 Queue
是通過peek和pop賦予它FIFO(在后面添加,從前面刪除)語義的原因。
LinkedBlockingQueue可以是有界的,這是您的標准之一。 還有其他幾個並發隊列和Deques可供選擇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.