page contents

ConcurrentHashMap源码关于table初始化的一个问题

Pack 发布于 2020-01-16 16:31
阅读 462
收藏 0
分类:Java开发

attachments-2020-01-r7nhC2U55e201f425fd4b.png
各位大佬好,这段代码就是table的初始化逻辑啦。其中的CAS操作我没太理解。
这里有一个大写的long类型的SIZECTL和一个小写的int类型的sizeCtl。

第一个问题:那么在cas操作里为什么要拿SIZECTL和被小写sizeCtl赋值过的sc进行比较呢?Mic老师上课说这是该对象在内存中的偏移量,那应该是一个很复杂的数吧,怎么能用来和sc比呢?比完之后又被赋值成了-1,那就又不是偏移量了?不是应该把sizeCtl赋值成-1么?

第二个问题:这里的this指的什么我还不是特别明白。当前对象指什么?

肯求解惑

206
Pack
Pack

反过来回答,先说第二个问题。


this就是你所理解的当前对象,对jvm来时,就是虚拟机上的一个地址。


在cas操作里为什么要拿SIZECTL和被小写sizeCtl赋值过的sc进行比较呢?


1.首先看SIZECTL,private static final long SIZECTL;一个静态常量,所以在加载完成后,这个值就不会在变化了。

2.SIZECTL = U.objectFieldOffset(k.getDeclaredField("sizeCtl"));通过sun.misc.Unsafe来获取SIZECTL当前对象的堆栈中找到变量sizeCtl的偏移位置。

3.U.compareAndSwapInt(this, SIZECTL, sc, -1)则是通过this和偏移量SIZECTL找到当前时刻sizeCtl的值(这个值肯定是最新的)和sc进行比较,如果相同则sizeCtl置为-1.在初始阶段都是为0,所以有且只有一次成功执行这个方法。

4.为什么用sun.misc.Unsafe来操作?可以理解为这是个原子操作(自带锁功能,由底层实现),如果同时有多个线程执行这个方法,只有一个会成功。

请先 登录 后评论