ConcurrentHashMap原理,jdk7和jdk8版本的区别

ConcurrentHashMap 是 Java 中用于高并发场景的线程安全的哈希表实现。它在 JDK 7 和 JDK 8 中的实现原理有显著的区别,主要是为了提高并发性能和扩展性。下面我们从原理、实现细节和版本区别等方面详细分析。


1. ConcurrentHashMap 的设计目标

  • 线程安全:支持高并发读写操作。

  • 高性能:尽量减少锁的竞争,提高并发性能。

  • 扩展性:支持动态扩容,适应数据量的增长。


2. JDK 7 中的 ConcurrentHashMap

实现原理:
  • 分段锁(Segment Locking)

    • JDK 7 中的 ConcurrentHashMap 使用分段锁机制,将整个哈希表分成多个段(Segment),每个段是一个独立的哈希表,拥有自己的锁。

    • 每个段相当于一个小的 HashTable,锁的粒度从整个表缩小到段级别,减少了锁竞争。

  • 数据结构

    • 每个段内部是一个数组 + 链表的结构。

    • 通过 Segment 数组和 HashEntry 链表实现。

核心代码:
final Segment<K,V>[] segments; // 分段数组

static final class Segment<K,V> extends ReentrantLock {
    transient volatile HashEntry<K,V>[] table; // 哈希表
}

static final class HashEntry<K,V> {
    final int hash;
    final K key;
    volatile V value;
    volatile HashEntry<K,V> next;
}
优点:
  • 分段锁减少了锁竞争,提高了并发性能。

  • 适合中等并发场景。

缺点:
  • 分段锁的粒度仍然较大,高并发场景下性能有限。

  • 实现复杂,代码维护成本高。


3. JDK 8 中的 ConcurrentHashMap

实现原理:
  • CAS + synchronized

    • JDK 8 中的 ConcurrentHashMap 抛弃了分段锁,改用 CAS(Compare-And-Swap)和 synchronized 实现线程安全。

    • 锁的粒度从段级别缩小到桶级别(每个桶是一个链表或红黑树),进一步减少了锁竞争。

  • 数据结构

    • 使用数组 + 链表 + 红黑树的结构。

    • 当链表长度超过阈值(默认 8)时,链表会转换为红黑树,提高查找性能。

核心代码:
transient volatile Node<K,V>[] table; // 哈希表

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    volatile V val;
    volatile Node<K,V> next;
}

static final class TreeNode<K,V> extends Node<K,V> {
    TreeNode<K,V> parent;  // 红黑树节点
    TreeNode<K,V> left;
    TreeNode<K,V> right;
    TreeNode<K,V> prev;    // 双向链表
    boolean red;
}
优点:
  • 锁粒度更小,并发性能更高。

  • 数据结构更高效,链表和红黑树的结合提高了查找性能。

  • 实现更简洁,代码更易维护。

缺点:
  • 实现复杂度较高,尤其是红黑树的插入、删除和平衡操作。


4. JDK 7 和 JDK 8 的区别

特性JDK 7JDK 8
锁机制分段锁(Segment)。CAS + synchronized(桶级别锁)。
数据结构数组 + 链表。数组 + 链表 + 红黑树。
锁粒度段级别(较大)。桶级别(较小)。
并发性能中等。高。
扩容机制分段扩容。整体扩容。
实现复杂度较高。较高(红黑树操作复杂)。

5. 核心操作原理

(1) put 操作
  • JDK 7

    • 根据键的哈希值定位到对应的段。

    • 获取段的锁,然后在段内的哈希表中插入或更新键值对。

  • JDK 8

    • 根据键的哈希值定位到对应的桶。

    • 如果桶为空,使用 CAS 插入节点。

    • 如果桶不为空,使用 synchronized 锁住桶的头节点,然后插入或更新键值对。

    • 如果链表长度超过阈值,将链表转换为红黑树。

(2) get 操作
  • JDK 7

    • 根据键的哈希值定位到对应的段。

    • 在段内的哈希表中查找键值对。

  • JDK 8

    • 根据键的哈希值定位到对应的桶。

    • 在链表或红黑树中查找键值对。

(3) 扩容
  • JDK 7

    • 分段扩容,每个段独立扩容。

  • JDK 8

    • 整体扩容,所有桶一起扩容。


6. 使用场景

  • JDK 7

    • 适合中等并发场景。

  • JDK 8

    • 适合高并发场景,性能更高。


7. 总结

特性JDK 7JDK 8
锁机制分段锁。CAS + synchronized
数据结构数组 + 链表。数组 + 链表 + 红黑树。
锁粒度段级别。桶级别。
并发性能中等。高。
实现复杂度较高。较高。

8. 一句话总结

  • JDK 7:分段锁机制,适合中等并发场景。

  • JDK 8:CAS + synchronized,锁粒度更小,适合高并发场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EthanMilk

你的鼓励是我创作的最大动力谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值