这是我不了解并发线程和原子操作的一件事。根据docs.oracle,这些操作被指定为原子操作:
但与此同时,docs.oracle断言,增量变量不是原子操作。我以为这是一篇文章:
private int number;
number++;显然,我不明白“读”和“写”是什么意思。
有人能解释一下这一点并给出一个“读”和“写”的例子吗?
编辑:在没有同步的情况下,程序会受到线程的干扰。所以我知道它不是原子的。但是,当我更改另一个属于这些线程共享的对象的变量时,没有任何干扰。来自此对象的共享变量通过一个mutator进行更改。
发布于 2014-03-24 13:22:20
为了实现number++,运行时需要
number的当前值(a读)。number (一个写)。如果另一个线程在2岁时从1开始,那么number的最终值将是不正确的,因为该线程仍将读取原始值。
如果将1、2和3作为原子操作执行(即,在完成3之前线程不能启动1),那么一切都会好的。
发布于 2014-03-24 13:26:29
您是正确的,number++涉及一个写,但它也涉及一个读。根据定义,原子操作是完全成功或完全失败的单个操作。因为number++执行多个独立的操作,所以它不是原子的。但是,有一些API可以作为一个单独的操作原子地增加一个值。在运行时,这些API使用专门的CPU指令,这些指令可以作为单个工作单元同时执行读和写操作。
对字对齐、字大小(或较小)值的单个读或写是原子的,例如:
int x;
x = 5 // write 'x'
5 + x // read 'x'因此,您可能确实理解读或写是什么;您可能没有考虑到++操作符是谨慎地执行这两种操作。
在没有同步的情况下,程序会受到线程的干扰。所以我知道它不是原子的。但是,当我更改另一个属于这些线程共享的对象的变量时,没有任何干扰。来自此对象的共享变量通过一个mutator进行更改。
如果您在没有同步机制或原子操作的情况下操作共享数据,并且您没有看到数据竞赛,那么您只是运气好,或者数据竞赛正在发生,而您没有注意到。在没有看到实际代码的情况下,很难说。
发布于 2014-03-24 13:25:12
递增一个值和引用一个值并不是一回事,也是一个和:这打破了原子性,因为不仅仅是简单的读或写。
https://stackoverflow.com/questions/22610603
复制相似问题