ConcurrentHashMap是如何保证线程安全的-put方法简要分析

简介

ConcurrentHashMap 是 Java 中并发编程中常用的线程安全的哈希表(HashMap)实现。它具有以下几个显著的特点和优点,适合在特定的并发场景中使用:

  1. 线程安全性

    • ConcurrentHashMap 提供了并发访问的线程安全保证,可以安全地在多线程环境中进行读取和写入操作,而无需显式地使用外部同步机制(如 synchronized)。
  2. 分段锁设计:--- jdk 1.7

    • ConcurrentHashMap 使用了分段锁(Segmented Locking)的技术,内部分为多个段(Segment),每个段都类似于一个小的 HashMap,各自维护一部分数据。
    • 默认情况下,ConcurrentHashMap 中有 16 个段,因此支持最多 16 个线程同时进行写操作,这提高了并发性能。
  3. 高并发性能

    • 分段锁设计使得 ConcurrentHashMap 在读操作上可以实现真正的并发访问,即使在写操作也只会锁住对应的段而不是整个表,因此不同段之间的操作可以并行执行,提高了并发性能。
  4. 扩展性和灵活性

    • ConcurrentHashMap 在初始化时可以指定段的数量,可以根据实际需求调整以平衡并发性能和内存消耗。
    • 它支持高并发的写入操作,同时保持良好的读取性能,适合于大部分读多写少的并发场景。
  5. 迭代安全性

    • ConcurrentHashMap 在进行迭代时,不会抛出 ConcurrentModificationException 异常,因为它通过一种复杂的方式确保迭代器能够安全地遍历表中的元素,即使在并发修改的情况下也能保证一定的可靠性。

应用场景

ConcurrentHashMap 适用于需要高并发访问且需要线程安全的场景,特别是在以下情况下可以考虑使用它:

  • 缓存:作为缓存的数据结构,支持并发的读写操作,适用于需要快速访问和更新的缓存系统。

  • 高并发计数器:用于统计访问次数或计数器的场景,例如网站访问统计、计数等。

  • 分布式任务分发:在任务分发时,可以使用 ConcurrentHashMap 来存储任务状态或结果,多个线程可以并发地更新任务状态。

  • 实时数据处理:对于需要实时更新和处理的数据结构,如实时日志处理系统,ConcurrentHashMap 可以支持高并发的写入和查询操作。

总之,ConcurrentHashMap 是一个强大的并发工具,通过其优化的设计和分段锁机制,能够在高并发环境下提供良好的性能和线程安全保证,是并发编程中常用的选择之一。

ConcurrentHashMap是如何保证线程安全的?

ConcurrentHashMap 在 Java 7 中采用了一种称为分段锁(Segmented Locking)的机制来保证线程安全性。具体来说,它的线程安全性是通过以下几个关键点来实现的:

  1. 分段锁机制:--- jdk 1.7

    • ConcurrentHashMap 内部维护了一个由多个段(Segment)组成的数组,每个段其实就是一个小的 HashTable。
    • 默认情况下,ConcurrentHashMap 中有 16 个段,理论上可以支持同时进行 16 个写操作(插入或更新)。
  2. 段内操作的加锁

    • 每个段都是一个独立的 HashTable,它们之间是相互独立的,因此在进行操作时,只需要锁定需要操作的段,而不影响其他段的操作。
    • 这样做的好处是,在多线程的情况下,不同段的操作可以并行进行,提高了并发性能。
  3. 保证可见性

    • ConcurrentHashMap 使用了 volatile 变量来保证段数组的可见性,确保一个线程对段数组所做的修改对其他线程是可见的。
    • 这样可以避免由于缓存一致性导致的问题。
  4. 写操作的安全性

    • 在写操作(插入或更新)时,需要锁定对应的段,但这个锁定是针对段而不是整个 ConcurrentHashMap,这样做提高了并发度。
    • 这种方式下,不同段之间的写操作可以并行执行,只有在同一个段上的写操作才会被阻塞。
  5. 读操作的安全性

    • 读操作通常不需要加锁,因为段内的 HashTable 是线程安全的,读取操作是非阻塞的。

总结来说,ConcurrentHashMap 通过分段锁的方式,在保证整体数据一致性的同时,提高了并发度,避免了传统的全局锁对并发性能的影响。这种设计使得在多线程环境中,ConcurrentHashMap 可以提供较高的并发访问性能。

Java 8 ConcurrentHashMap 线程安全分析

CAS自旋(sun.misc.Unsafe U   # compareAndSwapObject) +  synchronized

源码分析 put(key,value)

如下判断顺序,保证先后关系:

1、如果map中的核心数组为空,那么当前线程尝试进行cas初始化数组,然后再次尝试put;

2、如果数组不为空,并且map中【数组at位置-哈希槽】为空,代表这个哈希槽没有node,那么尝试cas设置当前node到这个位置上;

3、如果数组中【数组at位置-哈希槽】不为空,并且当前位置node节点正在【转移-扩容中】,那么当前线程帮助旧的node进行转移;

4、如果数组在【数组at位置-哈希槽】不为空,并且位置node没有发生转移,则对哈希槽Node进行加锁,锁定位置,然后添加新的Node到链表或者红黑树中;

如下图:

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ConcurrentHashMap线程安全Map 实现类,它通过多线程并发访问的方式提高了读写效率,同时保证线程安全ConcurrentHashMap 通过以下几种方式保证线程安全: 1. 分段锁 ConcurrentHashMap 内部维护了一个 Segment 数组,每个 Segment 都是一个类似于 HashMap 的结构,包含了一个 HashEntry 数组和一个共享的锁。每个 Segment 负责管理其中一部分键值对,不同的 Segment 之间互不干扰。这种分段锁的策略提高了并发访问的效率,同时也保证线程安全。 2. CAS 操作 ConcurrentHashMap 的 put 操作是通过 CAS (Compare and Swap) 操作实现的。CAS 是一种乐观锁的实现方式,它通过比较当前值和期望值是否相等来判断是否需要更新值。如果当前值和期望值相等,则更新值,否则不更新。CAS 操作是一种无锁的操作,可以避免线程阻塞,提高并发访问的效率。 3. volatile 关键字 ConcurrentHashMap 中的 Segment 数组和 HashEntry 数组都是通过 volatile 关键字修饰的,保证了多线程环境下的可见性。volatile 关键字可以保证变量的修改对其他线程可见,从而避免了线程之间的数据不一致问题。 总之,ConcurrentHashMap 通过分段锁、CAS 操作和 volatile 关键字等技术手段保证线程安全。这些技术手段既可以保证高效的并发访问,又可以避免线程之间的竞争和冲突,从而实现了线程安全Map 数据结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

进窄门见微光行远路

如果对你有比较大的帮助

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

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

打赏作者

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

抵扣说明:

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

余额充值