一、volatile关键字的作用
volatile关键字可以保证变量的值被修改之后,在内存中被多个线程立马可见。
因为一般情况下,每个线程都有自己的工作内存,当值被修改之后,只是修改了工作内存中的值,在主存中无法立马可见。
而volatile关键字则是绕过工作内存,直接把修改后的值写回主内存,其他线程也从主内存中读取值。
这里涉及到Java的内存模型。volatile可以保证内存可见性。告诉程序读取被volatile关键字修饰的变量应该到主内存中取,而不是到线程的工作内存取。
二、Java内存模型JMM
Java内存模型规定了所有的共享变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中使用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主存之间进行数据同步进行。
三、代码示例
定义一个线程类
package concurrent;
public class MyThread implements Runnable {
private volatile boolean flag = true;
@Override
public void run() {
while (flag) {
System.out.println("--------标志位为true,线程执行中--------");
}
System.out.println("--------标志位为false,线程执行结束");
}
public void changeFlag() {
this.flag = false;
}
}
main方法测试
package concurrent;
public class VolatileTest01 {
public static void main(String[] args) throws InterruptedException {
// 开启线程
MyThread myThread = new MyThread();
new Thread(myThread).start();
// 线程持续执行1ms
Thread.sleep(1);
myThread.changeFlag();
}
}
观察日志
主线程通过调用myThread的changeFlag方法,改变了volatile关键字修饰的变量flag的状态,导致持续执行100ms的myThread线程执行了不同逻辑。
由此可见,volatile关键字保证了线程间变量的可见性。