多线程环境下共享变量的可见性体现:
线程A \线程B 同时操作共享变量c
会出现线程A更新了变量c的值,但是线程B读取不到更新后的值
Java层面通过提供的volatile指令来解决(用volatile共享变量,即可保证共享变量的修改可以立即在其他线程可见)
为什么会出现可见性问题:底层cpu高级缓存优化、编译器优化、指令重排序等导致代码指令执行的可见性和有序性
**JMM JAVA MEMORY MODULE **:(java 内存模型)java内存模型定义了共享内存中多线程程序读写操作的规范:在虚拟机中把共享变量存储到内存以及从内存中把共享变量取出来的底层实现细节,通过这些规则来规范内存的读写操作从而保证指令的正确性,它解决了cpu多级缓存优化、处理器优化、指令重排序导致的内存访问问题
JMM如何解决可见性:在硬件层面对于缓存一致性解决有总线锁和缓存锁(基于MESI协议实现)对于指令重排序,硬件层面提供了内存屏障指令(读屏障、写屏障、读写屏障)保证指令顺序,不同操作系统和硬件架构提供的内存屏障指令不一样,JMM则是多不同操作系统和硬件架构的一个抽象,对不同架构屏障指令通过外部统一指令volatie进行抽象,外部开发者使用volatile关键字,底层由jvm根据不同的平台调用相应的指令
JVM 可见性保障规则:
1.volatile
2.fianl
3.Happen- before 模型(满足happen-before原则的都可以保证可见性)
3.1:两个指令间存在依赖
3.2:volatile 变量规则
3.3:start规则
3.4:join规则