currenthashmap 1.8
1. 计算hash值时在原有高16位异或低16位的基础上与0x7fffffff以减少hash冲突
2. 数组上的元素可能是代表链表头结点的Node,也可能是TreeBin,TreeBin中记录了红黑树的根节点
3. 使用unsafe类的cas方法直接原子性地操作内存,修改获取变量值
4. TreeBin的hash值等于-2,链表Node的hash值大于0
5. table初始化时使用懒加载,最初只是设置初始化容量大小。真正的初始化放在第一次执行put时
6. 特殊的Node:ForwardingNode的hash值等于-1,扩容时使用
7. sizeCtl最初的值是根据给定容量计算出来的2的整数次幂。实际初始化完成后赋值为数组的容量,为size*LOAD_FACTOR
8. table是volatile修饰的,只是异味着对table的赋值能保证内存的可见性。修改table中元素并不能保证可见性(volatile修饰的是引用,不是对象本身)
9. 扩容transfer的实现思路:设定一个步长,一个线程一次处理[length-步长,length]之间的节点。当其他线程帮助处理的时候通过修改TRANSFERINDEX指示当前处理的
数组元素范围。数组中的某个桶处理完成或者原先就是null,将桶替换成ForwardingNode
10. 扩容时节点要么在原先的桶,要么在原先index+原数组长度的桶里面。为了提高效率,会获取到从链表尾部开始最长的属于同一个桶的链表。直接链到新的桶里面。
11. [length-步长,length]之间的节点只会有一个线程处理,helptransfer只能重新设置步长,再处理自己对应的桶