java中volatile关键字的作用


前言

记录java线程相关的知识


1、volatile

1.1、volatile保证可见性

volatile可以保证,若一个线程改变了某块内存的值,其他线程是可见的,以至于其他线程能及时更新这块内存。

  • 线程拥有自己的内存空间:
    每个线程在运行时,都有自己的空间去加载缓存中的值,如果一个值发生改变,会先改变在线程中的值,再在一定时间内同步到缓存中。

  • volatile可见性:
    当两个线程使用同一变量M时,线程1改变了M的值,如果不使用volatile,线程2可能感知不到M发生了改变,继续拿着M在缓存中的值运行。使用volatile的变量,在线程1改变M时,对其他线程来说就是可见的,就会去更新M的值。
    在这里插入图片描述

  • 其他发生内存刷新的情况:
    有些java代码是已经包含了刷新内存、内存同步的操作,这会使得一些变量不加volatile,也会在多线程中及时更新。例如:调用System.out.println()会刷新内存

1.2、volatile保证顺序性

volatile修饰的内存,可以(利用 jvm中的内存屏障)保证它在多个代码行中读写的执行是有顺序的。

1.2.1、重排序与内存屏障

  • 为什么会重排序?
    为了提高CPU效率,在结果一致性的前提下,在执行一些较为耗时的操作,CPU并不会空着等待它执行完毕再继续,而是继续执行下面的代码。
    在这里插入图片描述
  • 怎么阻止这种不按顺序执行的情况?
    如上图,在第二行和第三行之间加一条内存屏障指令,当机器读到内存屏障指令时,就知道要等上一行执行完,才能执行下一行。
    在这里插入图片描述

内存屏障有cpu级别的和jvm级别的,cpu级别靠汇编语言特有的指令实现

1.2.2、jvm中的内存屏障

jvm规范规定,jvm必须实现的4中屏障:LL、LS、SL、SS

L (Load) ,指的是从内存中读一个数据到CPU
S (Store),指的是从CPU中写一个数据到内存

LL指第一行是从内存中读一个数据到CPU,第二行也是从内存中读一个数据到CPU,中间加的内存屏障类型就叫LoadLoadBarrier

LS指第一行是从内存中读一个数据到CPU,第二行从CPU中写一个数据到内存,中间加的内存屏障类型就叫LoadStoreBarrier

面试题:DCL单例加不加volatile

DCL单例(Double Check Lock 双检查加锁机制的单例)

答案见 : 关于java中单例的几个疑问

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值