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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通