并发容器ConcurrentHashMap和CopyOnWriteArrayList

ConcurrentHashMap:线程安全的hashMap

CopyOnWriteArrayList:线程安全的List

BlockingQueue:接口,阻塞队列,适合数据共享通道

ConcurrentLinkedQueue:高效的非阻塞并发队列,使用链表,可以看作线程安全的LinkedList

ConcurrentSkipListMap:跳表,快速查找

Vector 和hashtable

效率低,使用synchronized 修饰方法

HashMap和ArrayList

ConcurrentHashMap 和 CopyOnWriteArrayList

绝大多数并发情况下,二者的性能都更好

为什么hashMap是线程不安全的?

同时put碰撞导致数据丢失

同时put扩容导致数据丢失

死循环CPU100%

 

JDK1.7 ConcurrentHashMap实现和分析

最外层是多个segment,每个segment的底层与hashmap相似,仍然是数组和链表组成的拉链法。

每个segment上了ReentrantLock锁,每个segment之间互不影响,提高效率。

默认有16个segment,最多支持16个线程并发写,不可以扩容。

JDK1.8 ConcurrentHashMap实现和分析

数组+链表+红黑树 CAS+synchronized

putVal流程

  • 判断 k,v 不为空
  • 计算hash值
  • 根据节点的类型来赋值,或者增长链表,或者给红黑树增加节点
  • 满足阈值就红黑树化
  • 返回oldVal

为什么要把1.7的结构改为1.8?

  • 数据结构 原来的并发度为16,现在为数组的大小
  • hash碰撞 原来链表的时间复杂度为O(N),现在先使用拉链法,后使用红黑树为O(log2N)

为什么要超过8转换为红黑树?

泊松分布,超过8的概率是非常小的

组合操作

replace

putIfAbsent

CopyOnWriteArrayList

代替Vector和SynchronizedList,他们的锁粒度太大,并发效率低。

使用场景

读操作需要尽可能的快,写操作可以慢一些。

读写规则

读取不需要加锁,写入不会阻塞读取操作,只有写入和写入之间需要进行同步等待。

在修改时将原来的数据进行拷贝再修改,最后将引用指向修改后的内容。原来的数据不做修改

缺点

数据过期 CopyOnWriteArrayList 只能保证最终的一致性,不能保证实时数据的一致性。迭代器的创建时间决定了能不能读到数据。如果希望数据马上读到,不要使用。

内存占用 在进行写操作时,内存中会存在2个对象的内存。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值