请稍等 ...
×

采纳答案成功!

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

关于atomic底层实现的问题

http://img1.sycdn.imooc.com//szimg/5af6c92d0001e81510001779.jpg
这里do里做的和while里能保证原子性?do时候拿出来的底层值,做CAS的时候底层值有可能变了吧?

正在回答

15回答

Jimin 2018-05-13 00:55:28

那个不是关键,你一直没抓住关键的点
cas这里是拿当前线程的值和内存里的值对比,相同才更新。而当前方法里的值都是当前线程得到的值。对比是通过cpu指令拿方法里传进去的当前线程的值和内存里的值对比。
你认真体会我这最近两次说的话

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-13 00:45:02

很明显你没抓住关键点。
cas方法做的是带判断的更新,本质上是内存里的值和当前线程的值相同才做一次更新并返回true,否则不更新返回false。同时,这个方法是底层方法,不是普通的java方法,不是java自己实现的,是借助cpu指令实现的,cpu指令保证了判断和更新原子执行。
当一次更新不成功时,循环执行这里等我操作:取出当前内存最新的值,继续按照cas这个机制去尝试更新,直至成功

1 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-13 00:50:05

先说一句,辛苦老师这么晚还回答问题。我再问一下,do里面的except 值和while里的except 值一定相等吗

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-13 00:38:51

我快疯了,想了好几个小时,查了很多资料,就是想不明白

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-13 00:37:31

cas那个方法是底层方法,native标识的,可以理解为直接操作cpu指令实现的,而可见性属于java层面的,这不是一回事

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-13 00:34:15

第一步,取出内存期望值except
第二步,将内存取出的except 和之前内存取出的offset做比较
第三步,如果比较结果是相等,将update更新到内存,否则进入下一个循环
第二,三步是原子性我明白,但第一步和第二三步并不具备原子性吧?如果在第一步和第二步中间另一个线程改变了内存的值,当前线程的再进行第二步时,是否存在内存不可见性?

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-12 23:54:44

关于CAS中compareAndSwapInt(var1, var2, var5, var5 + var4)的理解
compareAndSwapInt(var1, var2, var5, var5 + var4)换成 compareAndSwapInt(obj, offset, expect, update)能清楚一些,如果obj内的value和expect相等,就证明没有其他线程改变过这个变量,那么就更新它为update,如果这一步CAS没有成功,那就采用自旋的方式继续进行CAS操作。这块是一个CPU指令完成的,依旧是原子操作。

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-12 22:56:51

假如do中取到的var5是2,这时候别的线程修改var 2成了3,此时执行while中var2和var5都是2吧

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-12 21:53:45

do和while不需要原子,是通过无限循环保证最终能更新成功

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-12 21:52:37

老师,你说的我知道,我说的是do和while不是原子啊

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-12 21:49:33

while那里是将compare和更新两个合到一起原子实现

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-12 21:47:03

那do的时候我取到的值跟预期值相等,这时候另一个线程修改了底层的值,而我做while的时候并不知道底层的值已经变了吧?

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-12 21:35:58

do的时候会去内存里取当前最新的,cas方法会使用取到的值与待更新时的值进行比较,如果相同才会更新

0 回复 有任何疑惑可以回复我~
提问者 慕村5205094 2018-05-12 21:32:35

老师,您好,在cas 里会再从底层取一次内存里的值吗?还是直接拿的do里面从内存取过来的值?

0 回复 有任何疑惑可以回复我~
Jimin 2018-05-12 21:14:34

你好,这里就因为取到的最新值,在实际更新时可能发生变化,才有了do...while循环,cas在操作时会保证检查当前值与预期值相同才进行更新的。

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信