介绍
volatile修饰java 变量,在多线程场景下使用时,可以作为一个写多个读的场景,并且是安全的。
代码示例
package wang.conge.javasedemo.core.thread;
public class VolatileDemo {
public static void main(String[] args) {
Model model = new Model();
new Thread(()->{
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
model.setFlag(false);
}).start();
new Thread(()->{
while(model.isFlag()){
System.out.println(model.isFlag());
}
}).start();
}
static class Model{
private volatile boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
}
原理解释
- 监视器锁的happens-before规则保证释放监视器和获取监视器的两个线程之间的内存可见性,这意味着对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
- 监视器锁的语义决定了临界区代码的执行具有原子性。这意味着即使是64位的long型和double型变量,只要它是volatile变量,对该变量的读写就将具有原子性。如果是多个volatile操作或类似于volatile++这种复合操作,这些操作整体上不具有原子性。
- 可见性。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。
- 原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。