许多文档暗示我们不能在另外一个线程写入值时使用volatile
,例如,有一个布尔对象isRun
,如果两个或多个线程调用setIsRun(true/false)
,我们不能使用volatile
来装饰变量count
。
据我所知,volatile
可以让所有线程看到最新值,那么为什么我们不能在上面的情况下使用它?任何人都可以告诉我这个,谢谢!
答案 0 :(得分:0)
正如你所说。
volatile
- 保证线程之间的可见性。
synchronized
- 保证线程之间的原子性和可见性。
示例:
假设有两个线程A和B都可以访问以下变量。
public volatile int count = 0;
如果线程A执行以下操作
count++;
无法保证JVM以原子方式执行++
操作,即实际的3个JVM操作(读取,增量,写入)。如果存在竞争条件,则线程B有可能将陈旧值分配给count
。
如果您想要原子性,则需要使用synchronized
示例:
假设有两个线程A和B都可以访问以下变量和increment
方法。
private volatile int count = 0;
public synchronized void increment() {
count++;
}
现在,如果线程A进入increment
方法,它将获得一个实例级别的监视器锁定,只有当它存在increment
方法时才会释放。这保证了JVM指令的读取,递增和写入一个接一个地执行。