2

本文內容摘要:我有一組訂購商品,其訂購可能隨時間而改變。我需要能夠從多個線程遍歷這個集合,每個線程也可能需要更新這些項目的順序。對ConcurrentSkipListMap/ConcurrentSkipListSet中的鍵重新排序的原子方法?

例如,多個線程需要以某種任意排序順序訪問String鍵。他們的字符串不是根據自然順序排序,而是根據可能會改變的某些值進行排序(因此,自定義Comparator)。我最初的實現是使用TreeSet並對其進行同步。如果任何密鑰需要重新排序,則線程將從地圖中刪除密鑰,更新比較值並重新插入密鑰。要實現這一點,密鑰是本機String s,但比較器可以訪問這些值。這是一種奇怪的安排,其中鍵的順序可能會隨着時間而改變,但是由於改變的鍵總是被移除並在改變時重新插入,所以它似乎起作用。 (我想這也可以工作,如果String小號包裹另一個對象中。)

我最近才知道原來ConcurrentSkipListSet/ConcurrentSkipListMap實現它們基本上是線程安全的有序集合的(相應的地圖。)好像我現在可以循環訪問密鑰而不必鎖定整個數據結構。但是,有沒有一種方法可以使用它們以原子方式刪除某個鍵並將其替換爲另一個鍵,如上面所做的操作,以便其他迭代線程不會錯過該項目,並且無需使用synchronize塊?

如果任何人都可以爲這種類型的操作建議更好的數據結構,我也是耳朵!

+1

這種設計會讓我真的很緊張。比較器不應隨時間而改變。 – 2013-03-19 18:22:59

+0

對於需要維護一組對象的訂單可能會隨時間而改變的內容,您會提出什麼建議? – 2013-03-19 18:24:26

+0

每次都可以使用新的比較器進行排序的列表,或者,我會編輯我的StackOverflow問題,向我們提供有關使您需要這種數據結構的問題的更多詳細信息。 ;) – 2013-03-19 18:29:12

回答

3

是有辦法,我可以用它來去除原子鍵和另一個取代它,就像我上面所做的操作,讓其他迭代線程不會錯過的項目,而不必使用同步塊?

簡短的回答是否定的。如果您需要刪除並重新插入,那麼對於我所知的任何集合都沒有原子方法。

也就是說,有一種可能性是您將之前的項目重新插入到之前,將其從跳過列表中刪除。這會造成重複,但可能更容易處理,然後丟失一個條目。在更改對象之後,您將重新插入它,以便進行不同的排序。這假定該對象也是不平等的。但是,如果處理列表的其他線程無法處理重複項,那麼我認爲你是SOL。