volatile

本文详细探讨了Java中的volatile关键字,通过实例代码、字节码解析、JVM源码以及汇编指令,揭示了volatile如何确保可见性和有序性。在JVM层面,volatile写操作会插入内存屏障,而在硬件层面,lock指令确保了多核环境下的数据一致性。这些机制保证了并发编程中volatile变量的正确使用。
摘要由CSDN通过智能技术生成

作用

  • 可见性
  • 有序性

JAVA

先写个Demo

package demo;

public class VolatileDemo {
    static volatile int value = 0;

    public static void main(String[] args) {
        value = 1;
        System.out.println(value);
    }
}

关键就看对value的读写;

字节码

javap反编译一下

0: iconst_1      
1: putstatic     #2                  // Field value:I
4: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
7: getstatic     #2                  // Field value:I
10: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V

很明显putstatic,getstatic实现对static类型的value的读写;

JVM

话不多说直接上源码,先看写的情况:

// hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp

// 是否用volatile修饰
if (cache->is_volatile()) {
            // 把值写入内存,是一个store操作
            ...
            // 内存屏障,保证值写入内存之后再执行后面的指令
            OrderAccess::storeload();
}
// hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp

inline void OrderAccess::storeload()  { fence(); }
// hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp

inline void OrderAccess::fence() {
  // 只有多核环境下才需要内存屏障
  if (os::is_MP()) {
    // always use locked addl since mfence is sometimes expensive
#ifdef AMD64
    __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory");
#else
    __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory");
#endif
  }
}

汇编

__asm__ volatile表示执行内联汇编,并且禁止编译器对内联汇编优化;cc不重要;memory禁止编译器重排序,从软件层面保证了有序性;addl $0,0(%%rsp)把0加到rsp寄存器,就是个空操作,重点就是lock前缀;

硬件

上Intel开发者手册:

Locking operations typically operate like I/O operations in that they wait for all previous instructions to complete and for all buffered writes to drain to memory.

所有之前的指令完成后再把store buffer里的所有写操作刷入内存,cpu的嗅探机制发现store buffer刷新到内存会自动无效化自己的缓存,从硬件层面保证了有序性可见性

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值