1、并发Map存储的数据结构
数组+链表+红黑树,存储数据的单元是Node结构,Node结构有key,value以及指向下一个Node的引用,还有hash字段
2、并发Map的负载因子可以修改吗?可以指定吗?
普通的 HashMap 的负载因子可以修改,但是 ConcurrentHashMap 不可以,因为它的负载因子使用final关键字修饰,值是固定的 0.75 。
3、Node对象的hash字段在一般情况下,必须是>=0,为什么?
散列表在扩容的时候,会触发一个迁移数据的过程,把原表的数据迁移到扩容后的散列表的逻辑
如果 Node.hash = -1,表示当前节点是 ForWardingNode节点(表示已经被迁移的节点)。
如果 Node.hash = -2,表示当前节点已经树化,且当前节点为 TreeBin 对象,TreeBin 对象代理操作红黑树。
如果 Node.hash > 0,表示当前节点是正常的 Node 节点,可能是链表,或者单个 Node。
4、简述 ConcurrentHashMap 中 sizeCtl 字段的作用
sizeCtl = -1,表示正在初始化。有线程正在对当前散列表(table) 进行初始化操作。
ConcurrentHashMap 的散链表是延迟初始化的,在并发条件下必须确保只能初始化一次,所以 sizeCtl == -1 就相当于一个"标识锁",防止多个线程去初始化散列表。
具体初始化操作就是在initTable()方法中,会通过 CAS 的方式去修改 sizeCtl 的值为 -1,表示已经有线程正在对散链表进行初始化,其他线程不可以再次初始化,只能等待!
如果 CAS 修改 sizeCtl = -1 操作成功的线程,可以接着执行对散链表初始化的逻辑。而 CAS 修改失败的线程,在