原子动作 - 读写是什么意思?

时间:2014-03-24 13:19:05

标签: java atomic

我不了解并发性的一件事 - 线程和原子动作。根据docs.oracle,这些操作被指定为原子:

  • 读取和写入对于引用变量和大多数原始变量(除long和double之外的所有类型)都是原子的。
  • 读取和写入对于所有声明为volatile的变量都是原子的(包括长变量和双变量)。

但同时docs.oracle声称递增变量不是原子动作。我以为这是写作:

 private int number;
 number++;

显然我不明白“读”和“写”是什么意思。

有人可以解释一下并举一个“读”和“写”的例子吗?

编辑:在没有同步的情况下执行此操作时,程序会受到“线程干扰”的影响。所以我明白它不是原子的。但是,当我更改属于这些线程共享的对象的另一个变量时 - 没有任何干扰。 来自此对象的共享变量通过mutator更改。

3 个答案:

答案 0 :(得分:4)

为了实现number++,运行时需要

  1. 获取number的当前值(读取)。

  2. 增加该值。

  3. 将新值写回number(写入)。

  4. 如果另一个帖子从1开始,当你在2时,则number的最终值将不正确,因为该线程仍将读取原始值。

    如果1,2和3作为原子操作执行(即线程在你完成3之前无法启动1)那么一切都会好的。

答案 1 :(得分:1)

number++涉及写入是正确的,但它也涉及读取。根据定义,原子操作是完全成功或完全失败的单个操作。由于number++执行多个独立操作,因此它不是原子操作。但是,有一些API可以将值原子递增为单个操作。在运行时,这些API使用专门的CPU指令,这些指令能够将读取和写入作为单个工作单元执行。

单个读取或写入字对齐,字大小(或更小)的值是原子的,例如:

int x;
x = 5  // write 'x'
5 + x  // read 'x'

所以你可能了解读或写是什么;您可能不认为++运算符是离散执行的。

  

在没有同步的情况下执行此操作时,程序会受到“线程干扰”的影响。所以我明白它不是原子的。但是,当我更改属于这些线程共享的对象的另一个变量时 - 没有任何干扰。来自此对象的共享变量通过mutator更改。

如果您在没有同步机制或原子操作的情况下操作共享数据,并且您没有看到数据竞争,那么您只是幸运,或者数据竞争 正在发生,并且您没有注意到。没有看到你的实际代码就很难说。

答案 2 :(得分:0)

递增一个值并引用一个值与递增也不是一回事:这会破坏原子性,因为不仅仅是简单的读或写。

相关问题