Java并发编程 cpu volatile

synchronize 

存储在Markword对象头   前4个字节当中的第一个字节的后3个比特位

偏向锁101>轻量级锁 [000]>重量级锁 [010]

默认情况下是偏向锁是开启状态,偏向的线程 ID 0 ,偏向一个 Anonymous BiasedLock
如果有线程去抢占锁,那么这个时候线程会先去抢占偏向锁,也就是把 markword 的线程 ID 改为当
前抢占锁的线程 ID 的过程
如果有线程竞争,这个时候会撤销偏向锁,升级到轻量级锁,线程在自己的线程栈帧中会创建一个
LockRecord ,用 CAS 操作把 markword 设置为指向自己这个线程的 LR 的指针,设置成功后表示抢
占到锁。
如果竞争加剧,比如有线程超过 10 次自旋( -XX:PreBlockSpin 参数配置),或者自旋线程数超过
CPU 核心数的一般,在 1.6 之后,加入了自适应自旋 Adapative Self Spinning. JVM 会根据上次竞争
的情况来自动控制自旋的时间。
升级到重量级锁,向操作系统申请资源, Linux Mutex ,然后线程被挂起进入到等待队列。

 

volatile
解决的多线程下的线程可见性问题,用到了内存屏障  缓存锁

在MESI协议中,每个Cache line有4种状态,分别是:

1、M(Modified)
这行数据有效,但是被修改了,和内存中的数据不一致,数据只存在于本Cache中

2、E(Exclusive)
这行数据有效,和内存中的数据一致,数据只存在于本Cache中

3、S(Shared)
这行数据有效,和内存中的数据一致,数据分布在很多Cache中

4、I(Invalid)
这行数据无效

每个Core的Cache控制器不仅知道自己的读写操作,也监听其它Cache的读写操作,假如有4个Core:
1、Core1从内存中加载了变量X,值为10,这时Core1中缓存变量X的cache line的状态是E;
2、Core2也从内存中加载了变量X,这时Core1和Core2缓存变量X的cache line状态转化成S;
3、Core3也从内存中加载了变量X,然后把X设置成了20,这时Core3中缓存变量X的cache line状态转化成M,其它Core对应的cache line变成I(无效)

当然了,不同的处理器内部细节也是不一样的,比如Intel的core i7处理器使用从MESI中演化出的MESIF协议,F(Forward)从Share中演化而来,一个cache line如果是F状态,可以把数据直接传给其它内核,这里就不纠结了。

CPU在cache line状态的转化期间是阻塞的,经过长时间的优化,在寄存器和L1缓存之间添加了LoadBuffer、StoreBuffer来降低阻塞时间,LoadBuffer、StoreBuffer,合称排序缓冲(Memoryordering Buffers (MOB)),Load缓冲64长度,store缓冲36长度,Buffer与L1进行数据传输时,CPU无须等待。

1、CPU执行load读数据时,把读请求放到LoadBuffer,这样就不用等待其它CPU响应,先进行下面操作,稍后再处理这个读请求的结果。
2、CPU执行store写数据时,把数据写到StoreBuffer中,待到某个适合的时间点,把StoreBuffer的数据刷到主存中。

因为StoreBuffer的存在,CPU在写数据时,真实数据并不会立即表现到内存中,所以对于其它CPU是不可见的;同样的道理,LoadBuffer中的请求也无法拿到其它CPU设置的最新数据;

由于StoreBuffer和LoadBuffer是异步执行的,所以在外面看来,先写后读,还是先读后写,没有严格的固定顺序。

引发指令重排

对于处理器来说,内存屏障会导致cpu缓存的刷新,刷新时,会遵循缓存一致性协议。

lock解锁时,jvm会强制刷新cpu缓存,导致当前线程更改,对其他线程可见。

volatile:标记volatile的字段,在操作时,会强制刷新cpu缓存,标记volatile的字段,每次读取都是直接读内存

final:即时编译器在final写操作后,会插入内存屏障,来禁止重排序,保证可见性

缓存一致性协议:https://blog.csdn.net/m15517986455/article/details/83273183
指令重排序、内存屏障                          https://blog.csdn.net/qq_41973594/article/details/110452849

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值