Java的Volatile关键字
Java 的 volatile
关键字是用来标记 Java 变量是“存储在内存中的”。更精确的说,读取 volatile
变量时,会从内存中读取,而不是从 CPU 缓存中读取。写入 volatile
变量的值时,会写入到内存中去,而不是写入 CPU 缓存中。
volatile 可以保证可见性
volatile
可以保证变量变化跨线程的可见性。
在多线程应用中,因为性能的原因,线程可能会直接从 CPU 缓存中读取变量的值,而现在的电脑有不止一个 CPU,所以读到的变量的值可能是错的。如果是用 volatile
标记变量,可以保证每次读取变量的值都是从内存中读取,每次写入变脸的值,都会写入到内存中去。
volatile 的 Happens-Before 保证
- 如果线程 A 写入了一个 volatile 变量的值,然后线程 B 去读取这个变量的值。那么在线程 A 中,在写入 volatile 的值之前的其他所有变量,对线程 B 都可见。(因为写入 volatile 变量是,会把 CPU 缓存中的值都写入到内存中去)
- 由于性能的原因,JVM 可能会对代码执行进行重排序,但是这样造成的结果可能不是我们想要的。volatile 可以保证所有跟随在读或写 volatile 变量之后的指令不允许重排序,都会发生在读或写 volatile 变量之后。
只有 volatile 是不够的
如果多线程写入新值到共享的 volatile 变量中去时,有可能会出现竞态。
那么可以怎么做?
使用 synchronize
关键字
volatile 的性能
- 内存的速度比 CPU 缓存的速度慢
- volatile 不允许指令重排序
这两个原因造成 volatile 的性能不是很高。所以只有你需要使用 volatile 的时候才去使用它。