繁体   English   中英

ConcurrentHashMap初始化

[英]ConcurrentHashMap Initialization

我们在ConcurrentHashMap下面使用多线程应用程序中的Cache。

private static Map<String, TransactionPriceItemDetailSummaryVO> pritmSummaryMap = new ConcurrentHashMap<String, TransactionPriceItemDetailSummaryVO>();

我们正在创建130个正在访问和更新此Map的线程

最终地图的大小约为1亿个(对象)。

我已经在线阅读了我们需要为ConcurrentHasMap指定参数以提高其性能的信息。

谁能建议我们如何为案例计算参数?

另外,最佳实践是在此映射上调用clear()释放内存吗?

java doc出发: 理想情况下,您应该选择一个值以容纳与并发修改表一样多的线程。 既然你说

... 130个正在访问和更新此Map的线程

那你应该用

new ConcurrentHashMap<String, TransactionPriceItemDetailSummaryVO>(130)

就像@Bohemian所说的那样,请设置一些更大的值以避免调整大小。 仅在不需要内容时才呼叫清除。

您可以使用以下构造函数配置Map:

ConcurrentHashMap<K,V>(initialCapacity, loadFactor, concurrencyLevel)

initialCapacity :尽管您已经提到要插入100M对象,但是您是否要将它们保留在地图中? 还是像添加和删除对象? 如果要保留所有这些值而不是将其删除, 110_000_000将该值保留为110_000_000建议的110_000_000 ,否则,应在任何给定时间点将其保留为地图的平均平均大小。

loadFactor :较高的负载系数值会减少空间开销,但会增加查找成本。 这意味着它对getput有重大影响,因为这两种方法都在内部进行查找。 默认情况下,它是0.75 ,通常被认为是空间利用率和查找时间之间的良好折衷。

concurrencyLevel :并发更新线程的估计数量。 在这种情况下,您提到的数字是130

通过在调用clear()删除所有元素时进行分析,可以进一步挖掘上述值。

地图上有1亿个物体!

IMO,在静态映射中包含这么多的对象绝不是一个好主意。 另外,由于Map会占用大量内存,因此Java会占用大量内存。 您可能会在应用程序服务器中遇到频繁的内存不足错误,并且转储每次都始终在其顶部始终放置java.util.Map(后跟无用的哈希码)。

相信我,您不希望看到这样的困难。 另外,当有130个线程正在访问时,谁知道您的应用程序明天甚至可能拥有2亿个对象,那么第二天就将有3亿个对象! 始终牢记什么会导致此问题!

建议 :您可以继续进行序列化(通过转换为JSON?) TransactionPriceItemDetailSummaryVO并将其保存在Redis中。 感觉到一些可扩展性? 简单,将硬件添加到您的Redis服务器!

另外,Redis有许多到期政策(ttl,太好了!)

通过大量的条目和线程,您可以通过构造函数告诉它预期的大小,从而帮助实现更好的性能:

new ConcurrentHashMap<>(110_000_000, 10, 130);

尝试不同的数字以找出有效的方法。

请注意,有了这么多项目,您将获得较高的哈希冲突率。 考虑使用基于不同键的嵌套映射,以便每个映射具有较少的条目,例如1M以下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM