Java 内存模型

2022-01-10 16:31:39 浏览数 (1)

JUC

今天跟大佬交流了一下,聊到Java四种内存屏障,现在分享一下

一.内存屏障是为了限制重排序,所谓重排序,是编译器和处理器为了提高系统吞吐量,优化程序性能,而对指令顺序进行重排序

代码语言:javascript复制
1.LoadLoad 模型 Load1 LoadLoad Load2 保证load1的数据的装载在load2以及后续装载指令的装载
2.StoreStore 模型 Store1 StoreStore  Store2 保证Store1数据可见(刷新到内存中) 先于 Store2以及后续指令的存储
3.LoadStore 模型 Load1 LoadStore Store2 保证Load1的数据装载先于Store2以及后续存储指令的刷新
4.StoreLoad 模型 Store1 StoreLoad Load2 保证Store1的数据刷新先于Load2以及后续装载指令。只有当该内存屏障前的存储和装载完毕之后,才会通过屏障
补充: 数据加载与存储( Load-store )指令用于在存储器和处理器的寄存器之间传送数据。可以理解位加载是读,装载是写。

二.重排序在哪种情况下会发生,

代码语言:javascript复制
1.指令之间不存在依赖关系,不影响程序执行结果的正确性才会发生
2.当指令之间存在内存屏障时无法发生指令重排序

三.有哪些关键字会禁止指令的重排序

代码语言:javascript复制
1.volatile
        每一个volatile写之前会插入StoreStore屏障,volatile写之后会插入StoreLoad屏障,StoreStore屏障 会确保之前的数据被装载和刷新到内存
        每一个volatile读之后会插入LoadLoad屏障,LoadStore屏障
2.final 
        写final域:JMM禁止编译器把final域的写重排序到构造函数之外,编译器会在写final域之后return之前插入StoreStore内存屏障
        读final域:在一个线程中读对象引用与读final域禁止重排序(针对于处理器而言)而这两者存在间接依赖关系,编译器遵守间接依赖关系,因此编译器不会重排序这两个操作

本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名,转载请标明出处 最后编辑时间为: 2021/11/30 07:31

0 人点赞