多线程-内存屏障(Memory Barriers / Fences)

是一种屏障指令,它使得CPU或编译器对屏障指令的前和后所发出的内存操作执行一个排序的约束。也叫内存栅栏或栅栏指令,volatile实现了Java内存模型中的可见性和有序性,但volatile无法保证原子性。

内存屏障之前的所有写操作都要回写到主内存,

内存屏障之后的所有读操作都能获得内存屏障之前的所有写操作的最新结果(实现了可见性)。

因此重排序时,不允许把内存屏障之后的指令重排序到内存屏障之前。

对一个 volatile 域的写, happens-before 于任意后续对这个 volatile 域的读,也叫写后读。

作用

  1. 阻止屏障两边的指令重排序
  2. 写数据时加入屏障,强制将线程私有工作内存的数据刷回主物理内存
  3. 读数据时加入屏障,线程私有工作内存的数据失效,重新到主物理内存中获取最新数据

happens-before 之 volatile 变量规则

第一个操作

普通读写

volatile读

volatile写

普通读写

可以重排

可以重排

不可以重排

volatile读

不可以重排

不可以重排

不可以重排

volatile2写

可以重排

不可以重排

不可以重排

    当第一个操作为volatile读时,不论第二个操作是什么,都不能重排序。这个操作保证了volatile读之后的操作不会被重排到volatile读之前。

    当第二个操作为volatile写时,不论第一个操作是什么,都不能重排序。这个操作保证了volatile写之前的操作不会被重排到volatile写之后。

当第一个操作为volatile写时,第二个操作为volatile读时,不能重排。

四大内存屏障

屏障类型

指令示例

说明

LoadLoad

Load1;LoadLoad;Load2

保证load1的读取操作在load2及后续读取操作之前执行

StoreStore

Store1;StoreStore;Store2

在store2及其后的写操作执行前,保证store1的写操作已刷新到主内

LoadStore

Load1;LoadStore;Store2

在stroe2及其后的写操作执行前,保证load1的读操作已读取结束

StoreLoad

Store1;StoreLoad;Load2

保证store1的写操作已刷新到主内存之后,Ioad2及其后的读操作才能执行

1.  在每个 volatile 写操作的前⾯插⼊⼀个 StoreStore 屏障

StoreStore Barriers Storel;StoreStore;Store2
禁止重排序:一定是Storel的数据写出到主内存完成后,才能让Store.2
及其之后的写出操作的数据,被其它线程看到。
保证Stor1指令写出去的数据,会强制被刷新回到主内存中

2.  在每个 volatile 写操作的后⾯插⼊⼀个 StoreLoad 屏障

StoreLoad Barriers Storel:StoreLoad;Load2
禁止重排序:一定是Storel的数据写出到主内存完成后,才能让Load2来读取数据同时保证:强制把写缓冲区的数据刷回到主内存中让工作内存/CPU高速缓存当中缓存的数据失效,重新到主内存中获取新的数据

  1. 在每个 volatile 读操作的后⾯插⼊⼀个 LoadLoad 屏障

LoadLoad Barriers:Load1;LoadLoad;Load2
禁止重排序:访问Load2的读取操作一定不会重排到Load1之前保证Load2在读取的时候,自己缓存内到相应数据失效,Load2会去主内存中获取最新的数据

    2. 在每个 volatile 读操作的后⾯插⼊⼀个 LoadStore 屏障

LoadStore Barriers:Loadl;LoadStore;Store2
禁止重排序:一定是Load1读取数据完成后,才能让Store2及其之后的写出操作的数据,被其它线程看到。

对比锁理解

  1. LOCk指令,相当于内存屏障,功能也类似内存屏障的功能
  2. 首先对总线/缓存加锁,然后去执行后面的指令,最后,释放锁,同时把高速缓存的数据刷新回到主内存
  3. 在lock锁住总线/缓存的时候,其它cpu的读写请求就会被阻塞,直到锁释放。Lock过后的写操作,会让其它cpu的高速缓存中相应的数据失效,这样后续在读取数据的时候,就会从主内存去加载最新的数据加了Lock指令过后的具体表现,就跟JMM添加内存屏障后一样。 

总结

  1. volatile写之前的操作,都禁止重排序到volatile之后
  2. volatile读之后的操作,都禁止重排序到volatile之前
  3. volatile写之后volatile读,禁止重排序的
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值