hashMap的线程安全替代方案
补充下另外两点:
1.ConcurrentHashMap 这个版本之所以高,还有一个非常核心的原因就是:ConcurrentHashMap 的查询get方法是没有加锁的,读是没有锁,写的时候才会涉及到锁。
2.比如hashtable 、Collections.SynchronizedMap无论是读还是写都会加锁,ConcurrentHashMap读上是没有锁的(依赖于Volatile的可见性来解决),再加上ConcurrentHashMap 1.8版本又把锁的粒度降低了,所以在并发的情况下性能较高。
get方法只能保证看到之前完成的操作,无法保证看到正在进行中的操作。
1. 访问的绝大数变量是volatile类型的,如count,node.val,node.next
2. 访问的变量只有一个不是volatile的,即table[]得每个元素,也就是说可能刚才已经成功插入一个table[i]
=node,但是读的时候确是null
3. 当找不到的时候,它会在加锁的情况下再读一次

浙公网安备 33010602011771号
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方法流程图如下: