多线程的volatile关键字

1、volatile作用
轻量级的synchronized,保证多处理器开发中的共享变量的可见性,如果这个变量修饰符使用恰当的话,不会引起上下文的切换和调度。
2、执行流程
volatile进行写操作时,会多出一行汇编代码,即lock前缀指令
该指令在多核处理器中:
引起处理器缓存写到内存
Lock#信号会锁定访问的内存区域的缓存,并且写入到内存,使用缓存一致性来确保修改的一致性,此操作成为缓存锁定。锁总线开销较大,所有锁缓存。缓存一致性会阻止同时修改由两个以上处理器缓存的内存区域数据。
一个处理器的缓存回写到内存会导致其他处理器的缓存无效。
使用MESI控制协议去维护内部缓存和其他处理器缓存的一致性。处理器使用嗅探技术保证内部缓存、系统内存和其他处理器的缓存的数据在总线上保持一致,如果使用嗅探技术检测其他处理器打算写内存地址,则在下次访问相同内存地址时,强制执行缓存行填充
3、使用优化
使用队列集合类Linked-TransferQuene,使用volatile变量时,采用追加方式优化队列出队和入队的性能。
追加到64字节是因为大部分处理器L1,2,3的高速缓存行时64个字节带宽,不支持部分填充缓存行,当队列头结点和尾结点都不足64字节,处理器会将其读入一个高速缓存行,将整个缓存行锁定,在缓存一致性的作用下,导致其他处理器不能访问自己的高速缓存行的尾结点,入队和出队需要不断修改头尾结点,严重影响效率。如果追加64字节方式填满高速缓存行,避免头尾结点加载到同一缓存行,则头尾结点不会在修改时互相锁定。
追加场景:
缓存行非64字节宽的处理器
共享变量不会被频繁写,追加方式需要处理器读取更多字节到高速缓存区,具有一定性能消耗,如果共享变量不会频繁被写,锁的几率很小,则没必要追加方式避免相互锁定。Java7后可能不生效。

 

posted @ 2020-05-11 08:45  久别重逢  阅读(142)  评论(0编辑  收藏  举报