Java线程内存模型跟CPU缓存模型相似,是基于CPU缓存模型来创建的,Java线程内存模型是标准化的,屏蔽掉了底层不一样计算机的区别。java
编写代码来分析编程
public class VolatileVisibilityTest { private static boolean initFlag = false; public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { System.out.println("等待数据准备.."); while (!initFlag){ } System.out.println("============数据准备完毕,执行程序逻辑"); } }).start(); Thread.sleep(2000); new Thread(new Runnable() { @Override public void run() { prepareData(); } }).start(); } public static void prepareData(){  System.out.println("数据准备中.."); initFlag = true; System.out.println("数据准备完毕!"); } }
执行程序,打印结果缓存
并未出现架构
============数据准备完毕,执行程序逻辑
这段结果并发
第一个线程给了initFlag为false,第二个执行了prepareData()因此initFlag为true,可是第一个线程中的flag仍是为false。ide
若是给initFlag加个volatile
关键字:性能
public class VolatileVisibilityTest { private static volatile boolean initFlag = false; public static void main(String[] args) throws InterruptedException { new Thread(new Runnable() { @Override public void run() { System.out.println("等待数据准备.."); while (!initFlag){ } System.out.println("============数据准备完毕,执行程序逻辑"); } }).start(); Thread.sleep(2000); new Thread(new Runnable() { @Override public void run() { prepareData(); } }).start(); } public static void prepareData(){ System.out.println("数据准备中.."); initFlag = true; System.out.println("数据准备完毕!"); } }
执行程序,返回结果线程
整个过程以下code
总线枷锁(性能过低)server
MESI缓存一致性协议
总线嗅探机制
能够感知到数据的变化从而将本身缓存里的数据失效。Volatile缓存可见性实现原理
Java程序汇编代码查看
IDEA这样设置
显式出的结果,其中volatile修饰的汇编代码以下:
0x000000000349eaff:
lock
add dword ptr [rsp],0h ;*putstatic initFlag
; - com.tugohost.concurrent.VolatileVisibilityTest::prepareData@9 (line 31)