查看完整视频
注册会员专属
您需要登录以后才能查看完整视频
评论可见
您需要在视频最下面评论,方可查看完整视频
积分观看
您支付积分,方可查看完整视频
{{user.role.value}}
付费视频
您支付费用,方可查看完整视频
¥{{user.role.value}}
专属视频
只允许以下等级用户查看该视频
会员专享
hashMap是线程不安全的,hashMap的线程安全替代方案有以下四个:
1、hashtable 对所有方法加锁(synchronized),所有线程锁的都是当前对象,锁的粒度太大
2、Collections.SynchronizedMap 锁的是同一个对象,每次锁的都是当前整张表,锁的粒度太大
3、ConcurrentHashMap JDK1.7 分段锁,通过hash计算,在找桶的位置之前,先去找锁的位置(对桶中位置分组的概念),缺点之一,每次确定位置,需要两次hash计算
4、ConcurrentHashMap JDK1.8 锁的粒度很小,当发生hash冲突的时候会去加锁,锁的是当前链表的头结点
实现方式:Node数组+CAS(桶中的头结点为空,用cas的方式做插入操作)+Synchronized(hash冲突,往后挂链表的时候加锁)+Volatile(多线程环境之下的可见性)
ConcurrentHashMap JDK1.8 put方法流程图如下:
言简意赅,直切重点 ✗棒棒的✗
这里我再补充下另外两点:
1.ConcurrentHashMap 这个版本之所以高,还有一个非常核心的原因就是:ConcurrentHashMap 的查询get方法是没有加锁的,读是没有锁,写的时候才会涉及到锁。
2.比如hashtable 、Collections.SynchronizedMap无论是读还是写都会加锁,ConcurrentHashMap读上是没有锁的(依赖于Volatile的可见性来解决),再加上ConcurrentHashMap 1.8版本又把锁的粒度降低了,所以在并发的情况下性能较高。