高并发容器

1. ConcurrentHashMap的加锁原理

ConcurrentHashMap是Java并发包java.util.concurrent中提供的一个线程安全的哈希表实现。在Java 8之前,ConcurrentHashMap使用分段锁(Segment Locking)来实现并发控制,每个Segment包含一个小的哈希表,多个Segment共同组成完整的ConcurrentHashMap。每个Segment有一个独立的锁,因此最多支持16个线程并发访问不同的Segment。

然而,在Java 8及以后的版本中,ConcurrentHashMap的加锁机制进行了改进,不再使用分段锁,而是采用了以下机制:

  1. CAS操作:ConcurrentHashMap使用无锁的CAS操作(Compare And Swap)来更新内部的一些计数器和链表节点。CAS是一种乐观锁,它通过比较内存中的值和预期的值,如果相同则更新为新值,这个过程是原子性的。-----自旋锁
  2. synchronized锁:对于哈希表中的每个桶(bucket),当需要对桶中的链表或红黑树进行操作时,会使用synchronized关键字对桶进行加锁。这种锁是针对单个桶的,而不是整个哈希表,因此锁的粒度更细,减少了锁竞争,提高了并发性能。
  3. 自旋锁和重试机制:在插入或更新操作时,如果遇到并发冲突,ConcurrentHashMap会采用自旋锁和重试机制来处理。线程会尝试多次获取锁,而不是一遇到冲突就阻塞,这样可以减少线程切换的开销。
  4. 扩容机制:ConcurrentHashMap支持并发扩容,当哈希表需要扩容时,会创建一个新的数组,并逐步将旧数组中的元素迁移到新数组中。这个过程是多个线程协同完成的,迁移过程中会保持数据的完整性。

2. CopyOnWrite

CopyOnWrite容器是Java并发包java.util.concurrent中提供的一种并发容器,主要用于读多写少的场景。CopyOnWrite容器的主要特点是:在读操作时,不加锁,而在写操作时,通过复制底层数组或数据结构来避免并发修改的问题。

CopyOnWrite容器在多个写操作时的处理流程:

  1. 线程A想要对容器进行写操作,如添加或删除元素。
  2. 线程A复制当前容器中的数组或数据结构,创建一个新的副本。
  3. 线程A在新副本上进行修改。
  4. 同时,线程B也想要对容器进行写操作。
  5. 线程B同样复制当前容器中的数组或数据结构,创建另一个新的副本。
  6. 线程B在它的副本上进行修改。
  7. 当线程A完成修改后,将新副本的引用更新到容器中,完成写操作。
  8. 同样,线程B完成修改后,也将它的副本的引用更新到容器中。

在这个过程中,虽然线程A和线程B都进行了写操作,但它们的操作是隔离的,因为它们各自操作的是不同的数组副本。最后,最后一个完成写操作的线程的修改结果会成为容器的最终状态。

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值