volatile有什么用?
把代码声明synchronized
有两个重要的后果,通常指该代码的原子性atomicty和可见性visibility。
- 原子性意味着 这个时刻只有一个线程能够执行一段代码,这代码通过一个monitor object保护。从而防止多个线程在更新共享状态时相互冲突。
- 可见性则更奇妙 ,他必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另外一个线程是可见的,如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致 的值,这将引发许多严重问题。
volatile 的使用条件
- volatile变量具有 synchronized 的可见性,但不具备原子性。这就是说线程能够自动发现 volatile 变量的最新值。
- volatile变量对于每次使用,线程都能得到当前volatile变量的最新值。但是volatile变量并不保证并发的正确性。
- Volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。
因此,单独使用 volatile 还不足以实现计数器、互斥锁或任何具有与多个变量相关的不变式(Invariants)的类(例如 “start <=end”)。
volatile的适用场景
模式 #1:状态标志
也许实现 volatile 变量的规范使用仅仅是使用一个布尔状态标志,用于指示发生了一个重要的一次性事件,例如完成初始化或请求停机。
volatile boolean shutdownRequested;
...
public void shutdown() {
shutdownRequested = true;
}
public void doWork() {
while (!shutdownRequested) {
// do stuff
}
}