【发布时间】:2017-08-12 08:39:30
【问题描述】:
我刚刚阅读了一个问题here,并阅读了评分最高的答案 @JB Nizet,我很困惑...... 根据答案,在下面的代码中,
private int a=0;
public void foo(){
int temp=35;
a=28;
a=temp;
}
a=28; 是一个原子操作。
在我在 Stackoverflow 中阅读的其他一些问题和答案中,信息有所不同,说 a=28; 是不是原子操作,因为首先对正确操作数的读取操作应该发生,然后写入操作发生,这两个操作中的每一个都是原子的,但整个分配不是(说实话,这就是我认为的工作方式)。
那么a=temp; 呢?就原子性而言,它与a=28; 有什么不同吗?
顺便说一句,我知道需要 volatile 对 double 和 long 进行原子读/写操作,只是对我上面写的内容感到困惑。
有人可以详细说明一下吗?
谢谢..
【问题讨论】:
-
您混淆了“操作”一词的范围。对
a的赋值是原子的,因为a是int。如果它是long,它就不会是原子操作。这与如何获得分配的值无关。没错,statement 不是原子的,但 assignment 操作 是。 -
顺便说一句,除了原子性之外,最好注意线程之间的可见性。有趣的例子:stackoverflow.com/questions/2787094/…
-
@Andreas,谢谢。我理解你所说的,对变量的实际写入是原子的。只是我在很多文档和书籍中看到像 a=temp; 这样的东西。是原子的,所以让我很困惑。我可以说 a=temp;不是原子的,如果 threadA 执行 a=temp; ,在读取 temp 和写入 a 之间,另一个 threadB 可以在 a 上交错,并在 threadA 写入之前读取 a 的值,因此使 a=temp;根据原子性的定义不是原子的?
-
@JamesJenkins 你是对的,另一个线程可以在读操作和写操作之间执行,所以赋值 statement 不是原子的。因为“原子”通常是关于操作,所以当你说它不是原子时,你应该确保澄清你在谈论语句,否则人们会误解你的方式你误解了你所读的内容。