这篇文章主要介绍了Java内存模型可见性问题相关解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
前言
之前的文章中讲到,JMM是内存模型规范在Java语言中的体现。JMM保证了在多核CPU多线程编程环境下,对共享变量读写的原子性、可见性和有序性。
本文就具体来讲讲JMM是如何保证共享变量访问的可见性的。
什么是可见性问题
我们从一段简单的代码来看看到底什么是可见性问题。
public class VolatileDemo { boolean started = false; public void startSystem(){ System.out.println(Thread.currentThread().getName()+" begin to start system, time:"+System.currentTimeMillis()); started = true; System.out.println(Thread.currentThread().getName()+" success to start system, time:"+System.currentTimeMillis()); } public void checkStartes(){ if (started){ System.out.println("system is running, time:"+System.currentTimeMillis()); }else { System.out.println("system is not running, time:"+System.currentTimeMillis()); } } public static void main(String[] args) { VolatileDemo demo = new VolatileDemo(); Thread startThread = new Thread(new Runnable() { @Override public void run() { demo.startSystem(); } }); startThread.setName("start-Thread"); Thread checkThread = new Thread(new Runnable() { @Override public void run() { while (true){ demo.checkStartes(); } } }); checkThread.setName("check-Thread"); startThread.start(); checkThread.start(); } }
上面的列子中,一个线程来改变started的状态,另外一个线程不停地来检测started的状态,如果是true就输出系统启动,如果是false就输出系统未启动。那么当start-Thread线程将状态改成true后,check-Thread线程在执行时是否能立即“看到”这个变化呢?答案是不一定能立即看到。这边我做了很多测试,大多数情况下是能“感知”到started这个变量的变化的。但是偶尔会存在感知不到的情况。请看下下面日志记录:
start-Thread begin to start system, time:1577079553515 start-Thread success to start system, time:1577079553516 system is not running, time:1577079553516 ==>此处start-Thread线程已经将状态设置成true,但是check-Thread线程还是没检测到 system is running, time:1577079553516 system is running, time:1577079553516 system is running, time:1577079553516 system is running, time:1577079553516 system is running, time:1577079553516 system is running, time:1577079553516 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553517 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519 system is running, time:1577079553519