从理论上讲,ConcurrentHashMap 的 Segment 和 HashMap 的 buckets 有什么区别?
What is the difference between Segment of ConcurrentHashMap and buckets of HashMap theoretically?
我了解到在HashMap中,条目(Key, Value)是根据hash(Key.hashCode)-->表示桶位置的索引放置在桶中的。如果一个条目已经放置在该位置,则会创建一个链表并将新条目(如果它具有不同的键 --> 通过 equals() 方法)放置在链表的开头。
- 我能否将此概念与 ConcurrentHashMap 的概念相关联,但不是 Buckets,而是个别线程锁定的 Segment。而不是条目,有 HashEntry(ies)。以类似的方式,创建一个链表,如果插入的键值对不同,则根据键的 equals() 将其放在链表的末尾。
- 我这样说对吗:
CHM 的 put 是不同步的,因此任何线程都可以访问这个方法,这个 put 方法计算传递给它的键的哈希值并得到段索引(有点像桶)。然后仅针对该段,它调用 put 方法。现在在 Segment 下,put 方法指定将有一个 lock(),因此只有一个线程可以更改特定段中的数据,因此得出结论,如果并发级别为 16,则应有 16 个线程,因此这些线程将是一次只能 PUT 值一个段。
桶是地图数组中的一个单独槽。这与 HashMap
和 ConcurrentHashMap
相同。从概念上讲,后者的数组被分成段(每个段是一个引用数组),仅此而已。注意Java8中的CHM不再有段,都是一个数组
是的,这是被称为分段锁定的方案。它减少了线程间争用,但并没有消除它。
我了解到在HashMap中,条目(Key, Value)是根据hash(Key.hashCode)-->表示桶位置的索引放置在桶中的。如果一个条目已经放置在该位置,则会创建一个链表并将新条目(如果它具有不同的键 --> 通过 equals() 方法)放置在链表的开头。
- 我能否将此概念与 ConcurrentHashMap 的概念相关联,但不是 Buckets,而是个别线程锁定的 Segment。而不是条目,有 HashEntry(ies)。以类似的方式,创建一个链表,如果插入的键值对不同,则根据键的 equals() 将其放在链表的末尾。
- 我这样说对吗: CHM 的 put 是不同步的,因此任何线程都可以访问这个方法,这个 put 方法计算传递给它的键的哈希值并得到段索引(有点像桶)。然后仅针对该段,它调用 put 方法。现在在 Segment 下,put 方法指定将有一个 lock(),因此只有一个线程可以更改特定段中的数据,因此得出结论,如果并发级别为 16,则应有 16 个线程,因此这些线程将是一次只能 PUT 值一个段。
桶是地图数组中的一个单独槽。这与
HashMap
和ConcurrentHashMap
相同。从概念上讲,后者的数组被分成段(每个段是一个引用数组),仅此而已。注意Java8中的CHM不再有段,都是一个数组是的,这是被称为分段锁定的方案。它减少了线程间争用,但并没有消除它。