jdk8concurrenthashmap头结点的 hash 值大于 0为啥是链表
时间: 2023-05-11 21:06:29 浏览: 96
化的起点?
这是因为 JDK8 中的 ConcurrentHashMap 使用了链表和红黑树两种数据结构来实现哈希表,当一个桶中的元素个数超过了阈值(默认为 8),且该桶的容量大于等于 64 时,该桶中的元素就会被转化为红黑树。而链表化的起点就是在插入元素时,如果该桶中已经存在一个元素,且该元素的 hash 值与要插入的元素的 hash 值相同,那么新元素就会被插入到该元素的后面,形成一个链表。
相关问题
jdk8 ConcurrentHashMap底层原理
JDK 8中的ConcurrentHashMap是一个线程安全的哈希表,它是通过分段锁(Segment)来实现并发访问的。下面是ConcurrentHashMap的底层原理:
1. 分段锁:ConcurrentHashMap将整个哈希表分成了多个段(Segment),每个段都是一个独立的哈希表,拥有自己的锁。不同的线程可以同时访问不同的段,从而提高并发性能。
2. Hash桶:每个段内部都由一个Hash桶数组组成,每个Hash桶中存储了一个链表或红黑树结构的键值对。通过哈希函数计算键的哈希值,然后根据哈希值找到对应的Hash桶。
3. 锁粒度:ConcurrentHashMap的锁粒度是段级别的,即每个段都有一个独立的锁。这样可以在多线程环境下实现更细粒度的并发控制,不同线程可以同时访问不同的段,提高并发性能。
4. 并发度:ConcurrentHashMap的并发度是通过调整段的数量来实现的。在创建ConcurrentHashMap时,可以指定初始段的数量,默认为16。随着元素的增加,ConcurrentHashMap会自动扩容,并重新计算元素在新段中的位置。
5. CAS操作:ConcurrentHashMap使用了CAS(Compare and Swap)操作来保证线程安全。CAS是一种无锁的原子操作,通过比较内存中的值与期望值是否相等来判断是否需要更新。如果相等,则进行更新操作;否则,重新尝试。
jdk1.8ConcurrentHashMap原理
ConcurrentHashMap是Java中线程安全的哈希表实现。在并发场景下提供高效的读写操作。下面是JDK 1.8版本ConcurrentHashMap的简要原理:
1. 数据结构:ConcurrentHashMap内部使用一个分段数组(Segment数组)来存储数据。每个Segment都是一个独立的哈希表,包含一个HashEntry数组。
2. Hash算法:ConcurrentHashMap使用了与HashMap相同的哈希算法。对于key的hashCode进行哈希操作,然后根据哈希值与Segment数组长度进行按位与运算,确定该键值对应的Segment。
3. 分段锁:每个Segment都有一个独立的锁,用于控制对该Segment内部数据的访问。这样不同的线程可以同时访问不同的Segment,提高了并发性能。
4. CAS操作:ConcurrentHashMap使用了CAS(Compare and Swap)操作来实现线程安全性。CAS操作是一种乐观锁机制,通过比较内存中的值与期望值是否一致来判断是否存在并发修改。
5. put操作:当执行put操作时,先对key进行哈希计算,确定对应的Segment。然后在该Segment上获取锁,并在该Segment的HashEntry数组中查找对应的位置。如果该位置为空,则直接插入键值对;如果该位置已经存在其他键值对,则进行链表或红黑树的处理。
6. get操作:当执行get操作时,同样需要先对key进行哈希计算,确定对应的Segment。然后在该Segment上获取锁,并在该Segment的HashEntry数组中查找对应的位置。如果该位置为空,则返回null;如果该位置存在键值对,则进行链表或红黑树的查找。
总结来说,ConcurrentHashMap通过分段锁和CAS操作实现了高效的并发访问。它允许多个线程同时访问不同的Segment,从而提高了并发性能。同时,它也使用了链表和红黑树等数据结构来解决哈希冲突问题,保证了较好的查询性能。
阅读全文