concurrentHashMap低层原理
时间: 2023-10-27 19:53:57 浏览: 99
ConcurrentHashMap 是 JDK 提供的线程安全的哈希表实现,相比于 Hashtable 和 synchronizedMap,它在高并发场景下的性能更好。
ConcurrentHashMap 的实现基于分段锁技术,内部维护了一个 Segment 数组,每个 Segment 充当一个小的哈希表,它们共同组成了 ConcurrentHashMap 的整个数据结构。在默认情况下,ConcurrentHashMap 会创建 16 个 Segment,每个 Segment 可以独立加锁,不同的线程可以同时访问不同的 Segment,从而提高了并发度。
每个 Segment 中的元素是根据哈希值存储在一个 HashEntry 数组中的。HashEntry 是 ConcurrentHashMap 中的一个内部类,它包含了键值对的信息,同时还包含了一个指向下一个元素的指针,这构成了一个链表。当多个线程同时访问一个 Segment 中的链表时,ConcurrentHashMap 会使用 CAS 操作对链表进行加锁,从而保证线程安全。
ConcurrentHashMap 在进行扩容时,会将原数组中的每个 Segment 扩容成一个更大的 Segment,并将其中的元素重新分配到新的 Segment 中。在扩容过程中,ConcurrentHashMap 仍然可以保证多个线程同时读写的线程安全性。
总之,ConcurrentHashMap 的核心思想是将一个大的哈希表分割成多个小的哈希表,并对每个小的哈希表进行加锁,以此来保证线程安全和高并发性能。
相关问题
ConcurrentHashMap的put原理
`ConcurrentHashMap`是`java.util.concurrent`包下的一个线程安全的哈希表实现,其`put`操作的核心原理基于红黑树和哈希表的结合:
1. **哈希表基础**:当尝试将键值对添加到`ConcurrentHashMap`时,首先会通过哈希函数计算出键的哈希码,然后根据这个哈希码确定存储位置。这一步非常快,因为它依赖于内存地址的计算。
2. **碰撞处理**:由于哈希函数不可能保证每个键都能得到唯一的槽位,所以可能会发生冲突(碰撞)。对于大多数哈希算法,如果两个键哈希到同一个槽位,就会形成链表,即所谓的开放寻址法。
3. **锁分离**:`ConcurrentHashMap`的设计允许并发地对不同桶进行操作。它使用分段锁(Segmented Locking)机制,每个桶对应一个独立的锁。这意味着当你在某个桶上添加元素时,其他桶上的操作可以继续,提高了并发性能。
4. **插入红黑树**:当链表长度超过8(这是内部设计的阈值),`ConcurrentHashMap`会切换到红黑树结构。此时,插入新元素不再直接追加到链表尾部,而是作为新节点插入红黑树中,保持树的平衡。插入操作会在树中进行,同时维护红黑树的性质(如颜色、度数等)。
5. **最终同步**:为了保证数据的一致性,当所有相关的修改完成后,可能会触发最终同步(Flush),比如删除了最后一个节点导致整个桶变为空或者红黑树转换回链表。这个过程会被加锁,确保在此期间线程安全。
总之,`ConcurrentHashMap.put`操作巧妙地利用了哈希表的快速查找和红黑树的高效排序,实现了高效的并发插入,并通过锁分离策略避免了全局互斥。
ConcurrentHashMap 实现安全原理
ConcurrentHashMap是一种线程安全的哈希表数据结构,它在保证并发访问的同时实现了高效的性能。它的安全性主要依赖以下几个核心设计原则:
1. **读操作不加锁**:对于读操作,ConcurrentHashMap内部使用了分段锁(Segmented locks),即对每个桶(bucket)独立加锁。这意味着大部分读操作可以在无锁状态下并行进行,只有当遇到写操作时才会同步。
2. **写操作加锁粒度低**:写操作会锁定整个桶,而不是整个表,这减少了锁竞争。写入时首先尝试cas(Compare and Swap)原子更新,如果失败则进入写链,这样可以避免长时间阻塞其他线程。
3. **读写分离和自适应大小调整**:读取操作通常比写入操作更常见,所以读操作通常优先使用无锁的方式。同时,ConcurrentHashMap会在负载较高时动态地增加容量,以减少因冲突导致的性能下降。
4. **弱一致性**:为了提高性能,ConcurrentHashMap牺牲了一部分强一致性,允许短暂的数据不一致。比如,putAll()操作可能会看到旧的键值对,直到所有修改都完成并且迭代器刷新。
5. **CAS和Fork-Join框架**:它广泛使用了Compare-and-Swap(CAS)操作以及Fork/Join框架来支持高效、非阻塞的并发。
阅读全文