volatile原理

时间:2021-7-3 作者:qvyue

一、并发编程特性

1、原子性:一个操作要么成功要么失败,中间不会中断

2、可见性:多个线程同时访问某个变量,当变量发生修改,其他线程可以立即看到被修改的值

3、有序性:代码按照代码的先后顺序执行

二、volatile可见性原理

volatile保证了可见性和有序性,可以有效的防止指令重排;

导致程序可见性问题,主要是因为当线程工作时,需要先把主内存中的变量拷贝(Load)到工作内存中,执行完成后,再写回(Store)到主内存中;所以这个中间就会存在多线程复写的问题;

volatile原理
主内存和工作内存

当加了volatile关键字,则通过”内存屏障”来防止指令重排;

1. lfence,是一种Load Barrier 读屏障

2. sfence, 是一种Store Barrier 写屏障

3. mfence, 是一种全能型的屏障,具备ifence和sfence的能力

4. Lock前缀,Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为CPU指令级的一种锁。它后面可以跟ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG等指令。

JVM提供的内存屏障:LoadLoad,StoreStore,LoadStore,StoreLoad;

可见性主要是通过MESI(修改 Modified  独享 Exclusive 共享Shared 无效 Invalid)机制来保证可见性;通过字节码可以看到,被volatile修饰的变量会有ACC_VOLATILE访问标识,通过汇编可以看到,执行时会lock

volatile原理
MESI

不同的硬件架构对MESI的实现不一样,一般CPU的三级缓存架构,读取缓存行(64byte)到cpu缓存,然后该CPU通过bus总线监控是否还有其他CPU读取该变量,通知也是通过总线通知;如果同时有其他线程对该变量进行修改,则会进行总线裁决;

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。