请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于compareAndSwapInt的

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回答

Jimin 2019-01-09 23:23:51

你好,你理解的是对的,在课程的问题汇总手记里我单独说了这个,地址在:http://www.imooc.com/article/25035

0 回复 有任何疑惑可以回复我~
磊磊要酷酷滴 2019-03-27 10:30:43

同意这位同学的观点,老师在讲解compareAndSwapInt(var1, var2, var5, var5 + var4)这个问题的时候确实是有问题的;查了OpenJDK的文档(因为Oracle的文档中Unsafe类的native方法是没有注释的),var2确实是偏移量,var1是个引用型变量,意味着var1指向对象的首地址,加上var2偏移量,可以定位到对象的某个成员变量或数组的某个索引上的值;有一点我认为可以有更好的解释,var1既然是AtomicInteger的this,那么在其中其实维护了一个共享变量count在线程中的私有拷贝;

1 回复 有任何疑惑可以回复我~
磊磊要酷酷滴 2019-03-27 10:38:06

给老师提一个建议:既然示例程序中count做的操作是自增,那么在讲解compareAndSwapInt(var1, var2, var5, var5 + var4)这个本地方法时为什么用的是2+1这个例子,让人突然跳出之前的思考,思路断了,再回过头对应到count++这个程序本身,理解上就更不容易;同意提问同学的建议,希望老师能重录这一章;

0 回复 有任何疑惑可以回复我~
  • Jimin #1
    好建议,我想一下如何优化一下这里视频的讲解
    回复 有任何疑惑可以回复我~ 2019-03-27 16:39:48
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信