2009-11-05 30 views
1

即使假設您將構建其他映射的成本排除在putAll()之外,通常(即不是併發),putAll()也不會比使用批次的put()更高效。這是因爲putAll()將需要迭代傳遞的Map元素,並且需要貫穿算法,將每個鍵值對添加到執行的映射。ConcurrentHashMap和putAll()方法

但是對於一個ConcurrentHashMap,構建一個常規Map然後使用putAll()來更新它是否有意義?或者我應該對put()進行10(或100,或1000)的呼叫?

對於putIfAbsent()的多次呼叫,答案是否會更改?

謝謝!

+0

你甚至使用線程來填充ConcurrentHashMap嗎?如果不是,則putAll()或100個連續put()的 – jitter 2009-11-05 02:18:07

+0

之間不會有任何區別是(至少)有一個線程正在寫入ConcurrentHashMap,並且多個線程正在讀取它。 – Rudiger 2009-11-05 02:25:18

+0

PutAll()就像是一個在CHM中添加多個元素的自動化過程,比一個一個地自己做。 – AKS 2013-08-20 04:14:10

回答

3

Java Collections中的第一個(大部分)線程安全映射是使用Collections.synchronizedMap()同步的HashMap。它一次只允許一次操作。 Java 5添加了ConcurrentHashMap,其工作方式不同。基本上Map分爲切片。 A put()操作將只鎖定相關切片。它還添加了線程安全基元,如putIfAbsent()

我解釋這個的原因是putAll()可能或多或少有效取決於它的實現方式。它可以通過鎖定整個地圖來工作,這實際上可能比試圖獲得每個put()上的個人鎖定更有效率。或者它可能通過做一堆put()調用,在這種情況下沒有太大的區別。

因此,如果它對您的代碼有意義,並且您正在進行大量更新,那麼我會使用putAll(),除非它是putIfAbsent()

編輯:我剛纔檢查時,Java 6 ConcurrentHashMap工具putAll()put()操作的循環,因此沒有比這樣做你自己更好或更壞。

+0

我認爲它可能會獲得所有更新的一個鎖,但我猜不是。我將對ConcurrentHashMap的'put()'進行單獨調用,並避免構建另一個Map的成本。 – Rudiger 2009-11-05 02:49:27

+0

查看源代碼的好處,但是我認爲「沒有更好或更差」,因爲更清晰的代碼更清晰代碼^^ – 2009-11-05 02:49:49

+0

有更清晰的代碼很好,但使用'putAll()'我必須創建一個新的Map(無論如何都會產生對put()的多次調用)。 – Rudiger 2009-11-05 03:00:24

2

putAll()只是代表put()。如果您還沒有建立中間地圖,則無需建立中間地圖。您可以在源代碼中看到這一點,因爲代碼是公有領域並且由所有人共享,所以您使用的Java實現無關緊要。

請注意,putAll()是不是原子,但只是保證每個人put()是原子。