volatile

本文探讨内存可见性在多线程中的重要性,深入解析volatile关键字如何确保数据一致性,以及happens-before规则的应用。通过讲解内存屏障和编译器策略,揭示volatile在防止重排序中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基本概念

  • 内存可见性:指线程之间的可见性,当一个线程修改了共享变量时,另一个行程可以读取到修改后的值。
  • 重排序:为了优化性能,对原有的指令执行顺序重新排序,重排序可能发生在多个阶段,比如编译重排序、CPU重排序等。
  • happens-before规则:是一个给程序员的使用规则,只要程序员遵循hanppens-before编码,JVM就能保证指令在多线程的执行顺序符合程序员的预期。

2.volatile的功能

  • 保证变量的内存可见性;
  • 禁止volatile变量和普通变量重排序。

2.1 volatile的内存可见性

当一个线程对volatile修饰的变量进行写操作时,JMM会把该线程对应的本地内存共享变量的值刷新到主内存中去。当一个线程对volatile修饰的变量进行读操作时,JMM会立即把本地内存对应的共享变量置为无效,从主内存中读取共享变量的值。
2.2 禁止重排序
主要是禁止普通变量和用volatile修饰的变量进行重排序。
JVM通过内存屏障来限制处理器的重排序。
内存屏障:分为读屏障(Load Barrier)和写屏障(Store Barrier).
内存屏障的作用:

  • 阻止屏障两边的指令进行重排序;
  • 强制把写缓存区/高速缓冲区中的脏数据写主内存中,

或者让缓存中相应的缓存失效(失效重新读取主缓存中的数据)
编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定的处理器重排序。编译器选择了JMM内存屏障插入策略。
屏障策略:
在每个volatile写操作之前插入StoreStore屏障;
在每个volatile写操作之后插入StoreLoad屏障;
在每个volatile读操作之后插入LoadLoad屏障;
在每个volatile读操作之后再插入一个LoadStore屏障。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值