浅谈CHM

put的全程操作:

(1)检查当前table是否初始化。如果没有初始化,首先初始化。设置sizeCtl为-1;然后初始化一个大小为16的数组。

(2)当sizeCtl为负数时,表示结构正在发生变化,所以此时其他线程的操作都会被阻塞,直到sizeCtl变回0;

(3)初始化之后,put值。

(4)如果之前已经初始化了,那么检查当前槽点是否为空,如果为空,cas插入;失败就继续自旋cas;直到成功;

(5)如果当前槽点不为空,检查是否是转移节点,如果是转移节点,那么久等待扩容操作完成;

(6)如果不是转移节点,那么久锁住槽节点,进行插入操作,直到插入完成;

(7)结束后检查是否需要扩容,如果需要就去扩容。

扩容操作:

(1)首先建立一个新的数组,大小是之前的两倍;

(2)然后从当前数组的队尾开始,转移槽点上的值到新数组上;当操作某个槽点时,会把原数组的槽点锁住,保证原数组的槽点不可操作,成功拷贝到新数组时,把原数组赋值为转移节点;

(3)这时,如果有新数据要put到这个槽点,就会发现它是转移节点,就会一直等待;

(4)当所有拷贝完成,就把新数组整个赋值给数组容器。

 

posted @ 2020-02-21 16:13  碧落君  阅读(174)  评论(0编辑  收藏  举报