为什么Volatile变量不用于Atomicity

Dif*_*ffy 1 java multithreading

来自Javadocs

使用volatile变量可降低内存一致性错误的风险,因为对volatile变量的任何写入都会建立与之后读取同一变量的先发生关系.这意味着对volatile变量的更改始终对其他线程可见.

当对volatile变量的更改始终对任何其他线程可见时,为什么在多个线程写入该变量的情况下不能使用volatile变量.为什么volatile只用于一个线程正在写入或读取的情况,而另一个线程只读取变量?

如果其他线程始终可以看到更改,则假设线程B想要写入该变量,它将看到新值(由线程A更新)并更新它.当线程A再次想要写入时,它将再次通过线程B看到更新的值并写入它.问题出在哪里?

简而言之,我无法理解这一点.

如果两个线程都在读取和写入共享变量,那么使用volatile关键字是不够的.在这种情况下,您需要使用同步来保证变量的读取和写入是原子的.

rua*_*akh 5

有很多用途volatile可以正常使用 - 但也有很多用途.例如,假设您有一个这样的字段:

private volatile int i;
Run Code Online (Sandbox Code Playgroud)

两个都运行的线程++this.i:读取this.i然后写入它.

问题是++this.i易失性读取后跟一个完全独立的易失性写入.在读取和写入之间可能发生了许多事情; 特别是,您可能会遇到两个线程i在任一线程写入之前读取的情况.净效果是值i增加了1,即使两个单独的线程都增加了它.

AtomicInteger(以及其他原子)通过允许您在单个原子(≈folatile)步骤中同时读取和写入来解决此类问题.(它们通过使用比较和交换指令来执行此操作,该指令仅在读取的值仍为当前值时执行写入.increation-and-get方法只运行一个循环,重试此操作直到写入实际成功. )

  • @Diffy所以你需要**读取**值,可能会检查它是你想要的值,然后**写**一个新值.这就是`++`的作用.作为一个群体,它不是"不稳定的". (3认同)