Java的内存屏障

目录

一、为什么要有内存屏障

1、原理解释

二、Java层面的内存屏障

1、Java的屏障类型

1.1、Load指令和Store指令

1.2、LoadLoad Barriers

1.3、StoreStore Barriers

1.4、LoadStore Barriers

1.5、StoreLoad Barriers

2、内存屏障在Volatile关键字里面的作用


一、为什么要有内存屏障

内存屏障是为了解决因为cpu,高速缓存,主内存出现的时候,导致的可见性重序性问题。

1、原理解释

因为计算机的运算任务需要CPU和内存相互配合共同完成,其中CPU负责逻辑计算内存负责数据存储。但是在真正的实际开发中CPU是要与内存进行交互的,但因为内存和CPU的计算速度是有差距的,因此为了提高CPU的利用效率,现代处理器结构都加入了一层读写速度尽可能接近CPU运算速度的高速缓存来作为内存与CPU之间的缓冲:将运算需要使用的数据复制到缓存中,让CPU运算可以快速进行,计算结束后再将计算结果从缓存同步到主内存中,这样处理器就无须等待缓慢的内存读写了。但在高速缓存解决CPU和内存之间速度的矛盾,但是在多CPU系统中也带来了新的问题:可见性问题和重排序问题。

二、Java层面的内存屏障

内存屏障(Memory Barrier)与内存栅栏(Memory Fence)是同一个概念,不同的叫法。而Java的层面 是应用volatile关键字去修饰变量,解决了编译器层面的可见性与重排序问题。

1、Java的屏障类型

Java中有四种类型:LoadLoad BarriersStoreStore BarriersLoadStore Barriers、 StoreLoad Barriers。从该四个类型中我们可以看到他们都是有Load和Store的不同排序组成。而这两个指令是来自硬件的内容。

1.1、Load指令和Store指令

Load指令(读屏障):它将内存存储的数据拷贝到处理器的缓存中。

Store指令(写屏障):它主要实现让当前线程写入高速缓存中的最新数据更新写入到内存,让其他线程也可见。

1.2、LoadLoad Barriers

简单的理解就是当有两个Load,一个Load1一个Load2,Load1加载代码要从内存里面读取的数据读取完毕之后,Load2加载代码才能读取数据。

1.3、StoreStore Barriers

理解为当有两个Store,一个是Store1一个是Store2,Store1的写入操作已经把数据写入到内存里面,并且保证Store1的写入操作对其它处理器可见之后,才会对Store2存储代码进行写入操作执行。

1.4、LoadStore Barriers

理解为当有一个Load1和一个Store2,要先保证Load1加载代码要从内存里面读取的数据读取完毕之后,Store2存储代码才会进行写入操作。

1.5、StoreLoad Barriers

理解为当有一个Store1和Load2,要先保证Store1的写入操作已经把数据写入到内存里面,并且确认Store1的写入操作对其它处理器可见,Load2加载代码才从内存里面读取数据。而且因StoreLoad Barriers同时具备其他三个屏障的效果,因此也称之为全能屏障,是目前大多数处理器所支持的,但是相对其他屏障,该屏障的开销相对昂贵的。

2、内存屏障在Volatile关键字里面的作用

每个volatile写操作前插入StoreStore屏障,这样就能让其他线程修改A变量后,把修改的值对当前线程可见,在写操作后插入StoreLoad屏障,这样就能让其他线程获取A变量的时候,能够获取到已经被当前线程修改的值

每个volatile读操作前插入LoadLoad屏障,这样就能让当前线程获取A变量的时候,保证其他线程也都能获取到相同的值,这样所有的线程读取的数据就一样了,在读操作后插入LoadStore屏障;这样就能让当前线程在其他线程修改A变量的值之前,获取到主内存里面A变量的的值。

参考的文章

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值