簡體   English   中英

Java ConcurrentHashMap中增加分區數的缺點?

[英]Disadvantage of increasing number of partition in Java ConcurrentHashMap?

Java ConcurrentHashMap在內部維護分區。 每個分區可以單獨鎖定。 可能存在多個線程訪問的所有密鑰落入同一分區並且分區可能沒有幫助的情況。 進一步增加分區數應該可以提高並發性。

為什么Java將分區計數的默認值設置為16而不是非常高的值? 地圖中有大量分區的表現是什么?

為什么Java將分區計數的默認值設置為16而不是非常高的值?

在同一時間使用相同的CHM時,很少有這些CPU(線程數不是那么重要)。 如果你真的需要這個,通常有一種更好的方法來編寫你的應用程序,避免這種情況。

例如,假設您有1000個線程但只有8個CPU。 這意味着最多只有8個線程將運行並訪問CHM,假設您的程序沒有做任何有用的事情,例如其他任何事情。

在實際程序中,很少有一個集合的使用時間超過10%。 這是因為通常會涉及一些IO,或者重組線程以使用自己的集合副本並在最后將它們收集在一起是有意義的,例如Map-Reduce

地圖中有大量分區的表現是什么?

你浪費了一些無關緊要的內存,但主要是你浪費了一些限制為32 KB的L1緩存和相對寶貴的資源。

這是javadoc所說的(Java 6):

“更新操作之間允許的並發性由可選的concurrencyLevel構造函數參數(缺省值16)引導,該參數用作內部大小調整的提示。該表在內部進行分區,以嘗試允許指定數量的並發更新而不會發生爭用。在散列表中基本上是隨機的,實際的並發性會有所不同。理想情況下,你應該選擇一個值來容納與同時修改表一樣多的線程。使用比你需要的值更高的值會浪費空間和時間,並且顯着較低的值可能導致線程爭用。但是在一個數量級內過高估計和低估通常不會產生明顯的影響。當知道只有一個線程會修改而其他所有線程只能讀取時,值為1是合適的。調整此調整或任何其他類型的哈希表是一個相對較慢的操作,因此,如果可能,提供預期的估計是一個好主意 構造函數中的表大小。“

所以簡短的回答是默認值(16)是限制並發和浪費空間之間的折衷。 “非常高”的價值會浪費很多空間。 (正如Peter Lawrey指出的那樣,由於內存緩存效應,可能導致性能下降。)

另一件需要注意的是LinkedHashMap實現默默地將concurrencyLevel的值限制為2 16 (至少,這就是Java 6代碼所做的。)很難想象一個真實世界的場景,你需要那么多的並發性。

暫無
暫無

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

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