网易云课堂学习-并发容器类ConcurrentHashMap/ConcurrentSkipListMap
jdk源码学习方法更重要
逻辑思维能力是梳理学习方法的基础。养车给你线性思维:两个或多个概念,像一条线串联起来。
jdk1.7中的HashMap
数组+链表的数据结构,头部插入(新的元素放在数组里面,旧的挤下去)。存放时是通过hash取余定位,有冲突的元素则通过放在链表头部来解决。
查找过程:hash+取余定位,再通过遍历链表来查找。
map扩容:
- map中的元素数量>=阈值(容量*加载因子)。
- 该次插入有冲突。
只有1,2两点同时满足时,才发生扩容。
3、扩容是创建新的数组,把老的数组的数据重新hash到新的数组上去。
问题:初始容量为16的map最多可以存放几个元素
答:应该是27个,既不是12也不是16。最多可以在一个数组位置插入12条数据。size是在插入之后才进行相加。所以在同一位置插入第12条数据时不会进行扩容。12+15=27。
HashMap-非线程安全
jdk1.8的HashMap源码分析
数组+链表(红黑树)的结构
扩容时机:
1、超过阈值(默认是12)
2、当链表长度超过8,且数组长度小于64的时候。
哈希冲突后新的元素是追加到尾部的。
链表长度超过树形转换阈值(8)后转变为红黑树。树的结构构建比较复杂。
为什么要转换?
因为当容量扩大到比较大时,每个链表的长度可能会很大,查询效率很低。使用树形结构,可以提升查询效率。
jdk1.7 ConcurrentHashMap源码解析
HashTable只有一把锁,并发能力较差。
相当于多个HashTable+负载均衡的功能。
并发量由segment的数量决定,每个segment可以看作时一个hashtable。默认是16个。
jdk1.8 ConcurrentHashMap