volatile修饰符---内存可见性+禁止重排

~本文小结:

  1. volatile是一个能保证变量的内存可见性,且禁止重排的修饰符;
  2. volatile通过设立4个内存屏障避免处理器的重排序;
  3. volatile可以作为一个锁使用(用于多线程同步);


1、volatile是什么?

  • volatile是一个Java修饰符;
  • volatile主要用于多线程同步;

2、volatile有啥功能?

volatile能保证变量的内存可见性。翻译成大白话:

被volatile修饰过的变量v,具有以下特点:

  • 按照代码顺序,对v的写happens-before对v的读取;
  • 只要尝试读取v,则该线程的本地内存立即与主内存同步;
  • 只要尝试写入v,则该线程的本地内存的改变,立即同步到主内存;
  • v不会和普通变量重排;(在对v操作上面的代码,一定已经被执行过了);

3、volatile如何禁止重排?

通过内存屏障实现。

内存屏障介绍:下述Load代表读操作,Store代表写操作
**LoadLoad屏障:**对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕。
**StoreStore屏障:**对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见。
**LoadStore屏障:**对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕。
**StoreLoad屏障:**对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的(冲刷写缓冲器,清空无效化队列)。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能

volatile给处理器设立的内存屏障:

  1. 在每个volatile写操作前插入一个StoreStore屏障;
  2. 在每个volatile写操作后插入一个StoreLoad屏障;
  3. 在每个volatile读操作后插入一个LoadLoad屏障+一个LoadStore屏障;
    在这里插入图片描述

4、volatile有啥用?

  • volatile可以保证内存可见性且禁止重排序;
  • volatile可以作为一个小小的锁来使用:其保证了对单个volatile变量的读/写具有原子性,且有内存可见性;其在性能上有优势;
  • 使用volatile能避免重排带来的问题;(单例模式—“双重锁检查”)

参考:

http://concurrent.redspider.group/article/02/8.html
《深入浅出多线程》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值