Java内存可见性

一、Java内存模型(JMM)

线程-》工作内存-》主内存

主内存

1、存储Java实例对象
2、包括成员变量、类信息、常量、静态变量等
3、属于数据共享区域,多线程并发操作时会引发线程安全

工作内存

1、存储当前方法的所有本地变量信息,本地变量对其他线程不可见
2、属于对主内存变量的拷贝
3、字节码行号指示器、native方法信息
4、属于线程私有数据区域,不存在线程安全问题

Java内存区域划分

主内存:堆和方法区
工作内存:程序计数器、虚拟机栈、以及本地方法栈

存储类型与操作方式

主内存:成员变量、static变量、类信息均被存储在主内存中
工作内存:方法里本地变量为基本数据类型将存储在工作内存的栈帧结构中;为引用类型引用存储在工作内存,实例存储在主内存中


二、JMM如何解决可见性问题

指令重排序

无法通过happens-before原则推到出来的,才能进行指令的重排序
A操作的结果需要对B操作可见,A与B存在happens-before关系,有八大原则

volatile(原则之一)

JVM提供的轻量级同步机制
1、保证被修饰的共享变量对所有线程可见
2、禁止指令的重排序优化
3、在多线程中运算符操作,并不保证安全性,大多数情况下可以使用synchronized来修饰执行运算的方法,它会创建内存屏障,保证所有CPU执行结果刷新到主存中

为何立即可见

写操作时,立刻将对应工作内存的值刷新到主内存的共享变量中
读操作时,把线程对应的工作内存置为无效,重新读取

如何禁止重排优化

内存屏障(Memory Barrier)

posted @   一颗米  阅读(109)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示