【发布时间】:2019-12-05 22:37:25
【问题描述】:
我一直在阅读 Brian Goetz 的 Concurency in Practice。
在Lock Striping一章中写到ConcurrentHashMap使用16个桶来改善多线程的多线程访问:
锁分割有时可以扩展到对可变大小的独立对象集进行分区锁定,在这种情况下,它被称为锁条带化。例如,ConcurrentHashMap 的实现使用了一个 16 个锁的数组,每个锁守卫 1/16 的哈希桶; bucket N 由 lock N mod 16 保护。
我已经阅读了这些问题:
Need simple explanation how “lock striping” works with ConcurrentHashMap
但是,这些答案对 Java 版本
对于 Java 8+,行为似乎发生了显着变化。对于 Java 8+,似乎不是为段获取锁,而是为表中的特定节点获取锁 (transient volatile ConcurrentHashMap.Node<K, V>[] table;)。例如putVal 操作:
ConcurrentHashMap.Node var7;
.... ///retrive node for var7
synchronized(var7) {
....
}
还有来自 Java8 + 字段的 DEFAULT_CONCURRENCY_LEVEL 和类 Segment 似乎在实现中未使用(它仅在私有方法 writeObject::ObjectOutputStream 中使用,并且在 ConcurrentHashMap 实现中的任何地方都不会调用此方法)。
ConcurrentHashMap实施发生如此重大变化的原因是什么?如果类
Segment未使用,并且像DEFAULT_CONCURRENCY_LEVEL这样的字段也未使用 - 为什么不从实现中删除它 - 是出于某些历史原因吗?如果我们不锁定段,就像以前用于 Java 版本
【问题讨论】:
-
如果您还没有找到这个:stackoverflow.com/questions/31577096/… -- 不回答您的问题,但包含更多信息。
-
分条,不是“分条”。
-
@user207421 为什么?
标签: java multithreading concurrenthashmap