volatile-两大特性(可见性、有序性)、内存屏障

本文探讨了Java中volatile关键字的两大特性——可见性和有序性,并深入解析了内存屏障的概念,特别是作为面试重点的内存屏障分类。

6.1 被volatile修饰的变量有两大特点 

● 特点:
  ○ 可见性
  ○ 有序性:有排序要求,有时需要禁重排

● 内存语义:
  ○ 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新回主内存中
  ○ 当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,重新回到主内存中读取最新共享变量的值
  ○ 所以volatile的写内存语义是直接刷新到主内存中,读的内存语义是直接从主内存中读取

● volatile凭什么可以保证可见性和有序性?
  ○ 内存屏障Memory Barrier

6.2 内存屏障(面试重点必须拿下) 

再说vilatile两大特性:
  ○ 可见:写完后立即刷新回主内存并及时发出通知,大家可以去主内存拿最新版,前面的修改对后面所有线程可见
  ○ 有序性(禁重排):
     重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段,有时候会改变程序语句的先后顺序,若不存在数据依赖关系,可以重排序;存在数据依赖关系,禁止重排序;但重排后的指令绝对不能改变原有的串行语义!这点在并发设计中必须要重点考虑!

6.2.3 内存屏障分类 

粗分两种:
● 读屏障(Load Barrier):在读指令之前插入读屏障,让工作内存或CPU高速缓存 当中的缓存数据失效,重新回到主内存中获取最新数据。
● 写屏障(Store Barrier):在写指令之后插入写屏障,强制把缓冲区的数据刷回到主内存中。

细分四种: 

### Java `volatile` 关键字与内存屏障有序性总结 #### 1. **什么是内存屏障** 内存屏障是一种同步机制,用于确保某些操作在特定顺序下完成。它是一个硬件级别的指令,在多核处理器环境中防止编译器优化或 CPU 的乱序执行行为。通过插入内存屏障,可以强制使屏障前后的读写操作按照指定顺序发生[^1]。 #### 2. **Volatile 内存屏障的关系** 当变量被声明为 `volatile` 后,Java 编译器会在对该变量进行读写操作时自动插入相应的内存屏障。具体来说: - 对于 `volatile` 变量的写入操作,会触发一个释放屏障 (Release Barrier),这确保在此之前的任何写操作都会先于该 `volatile` 写操作完成。 - 对于 `volatile` 变量的读取操作,则会触发一个获取屏障 (Acquire Barrier),从而保证此之后的任何读操作都不会提前到这个 `volatile` 读操作之前[^4]。 #### 3. **代码示例分析** 以下是基于提供的代码片段来说明 `volatile` 如何利用内存屏障保障有序性的: ```java public class MemoryBarrierExample { private int num; private volatile boolean ready; public void actor2(I_Result r) { num = 2; // 普通写操作 ready = true; // Volatile 写操作,带有 Release Barrier // 所有在此之前的操作(num=2)都被提交并可见给其他线程 } public void actor1(I_Result r) { if (ready) { // Volatile 读操作,带有 Acquire Barrier // 防止后续读取 num 提前至本语句之前 r.r1 = num + num; // 安全依赖于前面的条件判断 } else { r.r1 = 1; } } } ``` 在这个例子中: - 当线程调用 `actor2()` 方法并将 `ready` 设置为 `true` 时,由于这是一个 `volatile` 写操作,因此 JVM 自动在其前后插入了一个释放屏障。这意味着所有在线程 A 中发生在设置 `ready=true` 之前的修改(如 `num=2`),都将对其他线程变得可见。 - 在另一个线程中,如果检测到了 `ready==true` (即发生了 `volatile` 读操作),则因为存在获取屏障,所以能够确信此时看到的是最新状态下的数据,并且不会出现因重排序而导致逻辑错误的情况[^2]。 #### 4. **Volatile 的局限性** 尽管 `volatile` 能够很好地提供内存可见性一定程度上的有序性支持,但它并不能替代锁 (`synchronized`) 来处理复杂的并发场景。特别是对于复合动作或者涉及多个共享资源的状态更新而言,仅靠 `volatile` 并不足以满足原子性需求[^3]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZHOU_VIP

您的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值