目录
目标
HashMap
ConcurrentHashMap
认识了解ConcurrentSkipListMap
HashMap内部结构和原理
线程不安全:扩容时是非原子操作,会存在数据不完整,读的时候会存在问题,线程不安全。
从抽象角度,带着问题看源码,看最熟悉的方法,主要关注是什么而不是为什么这么做。
JDK1.7版本
存储数据结构:数据Entry<K,V>[] entry和链表结构,即数组加链表结构。
hash值:散列值,很难重复。
取模:计算数组下标。
hash碰撞:即使hash值不同,也可能下标相同。
扩容条件:是否达到指定的阈值,达到则扩容2倍。
JDK1.8版本
最大区别:当链表的长度大于8时,将链表转换成红黑树,提升查找的效率。
ConcurrentHashMap
JDK1.7版本
线程安全:使用分段锁来保证线程安全。
存储数据方式:Segment<K,V> segment[],此数组的长度也是并发级别,确定之后不可改变,默认值16,一个特殊的hashTable,使用分段锁的技术,太多并发级别消耗性能,
扩容:segments数组加链表的结构,原理和hashMap类似。
JDK1.8版本
线程安全:通过CAS争抢链表头部,失败后,使用synchronzed关键字锁住链表头部,即使用CAS+synchronzed达到线程安全,只是针对其中的一个链表加锁,可以很好的扩容。
存储数据方式:数组+链表结构,链表达到一定的阈值会转换成红黑树。
扩容:数组扩容,通过forwarding来实现扩容的线程安全。
ConcurrentSkipListMap
跳表
作用:线程安全,保证key的顺序,TreeMap能保证key的顺序,但是线程不安全。
通过key对数据进行排序,建立索引。
来源:CSDN
作者:阿莫西邻
链接:https://blog.csdn.net/xiaofbing/article/details/103743420