【问题标题】:Atomicity of Reads and Writes to Variables变量读写的原子性
【发布时间】: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 的赋值是原子的,因为aint。如果它是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 不是原子的。因为“原子”通常是关于操作,所以当你说它不是原子时,你应该确保澄清你在谈论语句,否则人们会误解你的方式你误解了你所读的内容。

标签: java atomic


【解决方案1】:

根据official documentation

对于引用变量和大多数原始变量(除了 long 和 double 之外的所有类型),读取和写入都是原子的。

由于a=28; 是对非长非双原语的写入,因此它是原子的。

但是a=temp 不是原子的,因为它由两个独立的操作组成——从temp 读取和写入int。它们中的每一个都是原子的,但不是它们的组成。

【讨论】:

  • 谢谢。我已经阅读了文档,仍然感到困惑。所以你说如果我使用文字,例如示例中的 28,则没有其他线程可以在 a=28; 上交错; ?但是,另一个线程可以在 a=temp 上交错,在读取 temp 和写入 a 之间,另一个线程可以进来并读取 a 的值……?
猜你喜欢
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
  • 2015-07-16
  • 2015-08-13
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多