关于compareAndSwapInt的
来源:3-1 线程安全性-原子性-atomic-1
![](http://img1.sycdn.imooc.com/user/5458625e000166a002190220-100-100.jpg)
慕粉13951610073
2019-01-09
compareAndSwapInt(var1, var2, var5, var5 + var4)这个
老师的解释是
var1:当前对象
var2:原来的值
var5:底层的值
var5 + var4 : 底层的值加上增长量
然后var2和var5比,一样就更新,不一样就不更新
然后很多同学,就整不明白了,比如下面:
do {
var5 = this.getIntVolitale(var1, var2);
} while(!compareAndSwapInt(var1, var2, var5, var5 + var4))
很多同学估计和我一样,一开始听视频,觉得有问题啊,既然var5是底层的值,
那么 var5 = this.getIntVolitale(var1, var2); 执行之后,
compareAndSwapInt(var1, var2, var5, var5 + var4)执行之前,
这个时候另外一个线程很可能己经跑过了,己经把底层值更新掉了。。
这个时候执行compareAndSwapInt(var1, var2, var5, var5 + var4))时候,不就有问题了
这个时候,var2和var5是一致的,然后我就更新,但其实var5是己经被更新掉了。这样不就有问题了吗?
------------------------------------
然后我调查了一下资料
var2:原来的值,这个解释不对(这个var2是个offset,是对象偏移量,学过汇编之类的,就知道了,类似于偏移地址,通过var1, var2可以取到底层中对应的值)
compareAndSwapInt(var1, var2, var5, var5 + var4))这句话我觉得这样说更好理解一点,
通过var1:当前对象加上var2:偏移量地址,定位到底层中对应的值,然后把这个值和var5进行比,
如果一样,就更新底层中对应的值,不一样说明己经被更新过了。重新走循环的逻辑,也就是所谓的自旋
----------------------------------------------------
var5 = this.getIntVolitale(var1, var2); 这个的意思应该是,var1:当前对象+var2:偏移量 ,可以取到底层中的实际值。
其实当前对象就是个地址,当前对象的地址加上偏移地址就能实际定位的某个具体的值了。
我的理解应该没啥问题吧?描述的可能不好。我觉得老师最好把视频修一下,不然估计很多同学都会有疑问
3回答
-
你好,你理解的是对的,在课程的问题汇总手记里我单独说了这个,地址在:http://www.imooc.com/article/25035
00 -
磊磊要酷酷滴
2019-03-27
同意这位同学的观点,老师在讲解compareAndSwapInt(var1, var2, var5, var5 + var4)这个问题的时候确实是有问题的;查了OpenJDK的文档(因为Oracle的文档中Unsafe类的native方法是没有注释的),var2确实是偏移量,var1是个引用型变量,意味着var1指向对象的首地址,加上var2偏移量,可以定位到对象的某个成员变量或数组的某个索引上的值;有一点我认为可以有更好的解释,var1既然是AtomicInteger的this,那么在其中其实维护了一个共享变量count在线程中的私有拷贝;
10 -
磊磊要酷酷滴
2019-03-27
给老师提一个建议:既然示例程序中count做的操作是自增,那么在讲解compareAndSwapInt(var1, var2, var5, var5 + var4)这个本地方法时为什么用的是2+1这个例子,让人突然跳出之前的思考,思路断了,再回过头对应到count++这个程序本身,理解上就更不容易;同意提问同学的建议,希望老师能重录这一章;
012019-03-27
相似问题