currentHashMap1.8扩容原理
时间: 2023-07-07 08:03:23 浏览: 148
ConcurrentHashMap 1.8 的扩容是基于 JDK 1.7 的实现进行优化的。
在 JDK 1.7 中,ConcurrentHashMap 的扩容是通过分段锁来实现的。具体来说,ConcurrentHashMap 会将其内部数据结构(Segment 数组)分成若干个段(Segment),每个段都有一个独立的锁。在扩容时,只需要对需要扩容的段加锁,其他段仍然可以正常读写,从而实现了并发扩容。
而在 JDK 1.8 中,ConcurrentHashMap 改为了使用 CAS 原子操作来实现扩容。它会先将整个 ConcurrentHashMap 分成若干个桶(table),每个桶中存储多个键值对。当需要扩容时,先创建一个新的桶数组,并将每个桶中的键值对重新计算 Hash 后,放入新的桶数组中。在放入新桶数组的过程中,通过 CAS 操作来保证线程安全。扩容完成后,新的桶数组会替换旧的桶数组,从而完成整个扩容过程。
需要注意的是,在扩容时,ConcurrentHashMap 会将每个桶中的键值对分拆成两个链表,分别放入新旧两个桶数组中。这是为了防止在扩容过程中,某个桶中的所有键值对都需要重新计算 Hash 的情况,从而导致大量的链表重建,影响扩容效率。
相关问题
currenthashmap 1.8底层原理
Java 1.8 中的 `ConcurrentHashMap` 底层使用了一种称为 "分段锁"(Segment)的技术,它将一个大的内部数组分成多个小的段(Segment),每个段都有自己的锁。这样,在多线程并发访问时,每个线程只需要获取自己访问段的锁,就可以进行读写操作,从而大大提高了并发性能。
具体来说,一个 `ConcurrentHashMap` 内部由多个 Segment(默认是 16 个)组成,每个 Segment 都是一个类似于 HashMap 的结构,其中包含了一个数组和一个链表,数组中存放了键值对的数组,链表则是解决哈希冲突的方式。
当一个线程要访问某个键值对时,它会先根据键的哈希值找到该键值对所在的 Segment,然后获取该 Segment 的锁,然后再进行读写操作。
由于每个 Segment 都有自己的锁,不同的线程可以同时访问不同的 Segment,从而提高了并发性能。同时,由于每个 Segment 内部的数据结构和 HashMap 类似,因此可以保证每个 Segment 内的操作都是线程安全的。
总之,ConcurrentHashMap 1.8 底层使用了分段锁的技术来保证线程安全和高并发性能。
currenthashmap在jdk1.8扩容处理逻辑是什么
在 JDK 1.8 中,`ConcurrentHashMap` 中的扩容处理逻辑与之前的版本有所不同。在 JDK 1.8 中,`ConcurrentHashMap` 使用了一种称为“分段锁”的技术,即将整个哈希表分成多个段,每个段都有一个独立的锁,这样不同的线程可以同时访问不同的段,从而提高了并发性能。
在扩容时,`ConcurrentHashMap` 会先将整个哈希表分成多个段,然后对每个段进行扩容。具体的处理逻辑如下:
1. 首先,`ConcurrentHashMap` 会计算新哈希表的大小,然后创建一个新的哈希表数组。
2. 然后,`ConcurrentHashMap` 会对每个段进行扩容。对于每个段,`ConcurrentHashMap` 会获取该段的锁,以确保在扩容过程中不会有其他线程修改该段。
3. 在获取到锁之后,`ConcurrentHashMap` 会将该段中的所有键值对复制到新的哈希表中。在复制过程中,`ConcurrentHashMap` 会使用一种称为“链表分裂”的技术,即将每个桶中的链表分成两个链表,一个是原链表中哈希值不变的键值对构成的链表,另一个是哈希值变化的键值对构成的链表。
4. 复制完成后,`ConcurrentHashMap` 会将新的哈希表赋值给该段的哈希表属性,并释放该段的锁。
5. 最后,`ConcurrentHashMap` 会对整个哈希表进行扩容完成的检查,以确保在扩容过程中没有其他线程修改了哈希表。
需要注意的是,在 JDK 1.8 中,`ConcurrentHashMap` 的扩容操作是分段进行的,因此扩容的过程不会对整个哈希表进行加锁,从而减小了锁的争用,提高了并发性能。
阅读全文