公众号merlinsea
背景
ConcurrentHashMap的出现目的就是为了解决HashMap在多线程环境下可能出现线程不安全问题。这里的线程不安全都是指的单JVM环境下的多线程操作!
JDK8之前,ConcurrentHashMap使⽤锁分段技术,将数据分成⼀段段存储,每个数据段配置⼀把锁,即segment类,这个类继承ReentrantLock来保证线程安全;技术点:Segment+HashEntry
JKD8的版本开始取消Segment这个分段锁数据结构,底层也是使⽤Node数组+链表+红⿊树,从⽽实现对每⼀个节点加锁,也减少了并发冲突的概率,CAS(保证读的线程安全性)+Synchronized(保证写的线程安全性) ;技术点:Node+Cas+Synchronized
总结put操作:
1、判断key,value是否为空,为空直接抛出空指针异常。
2、进行二次hash,得到hash值(二次hash目的在于hash效果更佳)。
3、判断table中对应的hash位置是否有元素,没有直接插入。
4、如果有元素,那么把这个Node节点作为锁对象传入syncronized。
5、如果是链表,那么按链表方式进行插入(找到相同的key就替换(不会发生链转树),否则进行尾插法(可能发生链转树))。
6、如果是红黑树,那么按照红黑树的方式进行插入。
7、最后判断是否需要链转红黑树。
注意: 插入操作采取的是尾插法,因为在put操作的时候会锁住头节点。
get操作