采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }
你好,var5只能保证取出的是当时内存里最新的值,不保证之后调用compareAndSwapInt
时依旧和内存里的值仍然一致。本身取出var5最新值后去调用compareAndSwapInt也不一定直接成功,就因为这两个操作本身不具备原子性。但这并不影响 getAndAddInt 整个方法要完成的事情,这个原因在于:
首先,compareAndSwapInt 这个native方法涉及到的”检查相等则更新,否则不更新“这两个操作是原子性的,cpu指令来保证。
其次,getIntVolatile 和 compareAndSwapInt 这两个操作中间确实可能有其他操作,也就是var5刚从内存取了一次,内存里的值就更新了。但是他不是只做一次的。compareAndSwapInt会去检查当前线程里获取的值和内存里最新的值是否相等,只要不等就继续重新获取var5的最新值并重试这个过程,直到相等才进行更新。
实际中,getIntVolatile和compareAndSwapInt 两个操作中间尽管会插入其他操作,但要重试好几次的概率其实很小,这里不需要纠结一直会重试下去的可能,这里只能说理论上有可能会重试很多次,实际会很快退出重试的。
这次是真的扫除了我理解上的误区了,var5不是和var1比,而是和内存中的最新值比,扫清了这个误区,就豁然开朗了。谢谢老师的耐心解答^_^
http://www.imooc.com/article/25035
这里老师有解答
http://coding.imooc.com/learn/questiondetail/96908.html
这个我觉得解释的更易懂
老师的回答和那位同学的回答都没能回答清楚;var5到底是不是主内存中的count在线程中的私有拷贝?如果是的话,私有拷贝当然可能落后于主内存中的count,而且这个落后的动作当然可以发生在两行代码之间,就是while循环的条件那一行。
每个人的理解多少都有些差异,因此一份回答不一定能满足所有人,你可以看看我针对你这个提问点的回答,是否能解答你的疑问,之前很多人是纠结compareAndSwapInt的原子性,因为这个方法有问题。
登录后可查看更多问答,登录/注册
构建完整并发与高并发知识体系,倍增高薪面试成功率!
1.7k 1
1.1k 18
1.2k 15
3.6k 12
1.3k 12