学习笔记:volatile关键字总结

volatile关键字

  • 1、Java的内存模型

    Java内存模型简称JMM(Java Memory Model),是Java虚拟机所定义的一种抽象规范,用来屏蔽不同硬件和操作系统的内存访问差异,让java程序在各种平台下都能达到一致的内存访问效果。
    这里写图片描述
    注意:
    1、主内存是被所有线程共享的,主内存中存储了共享变量的“本体”;
    2、工作内存就是线程拥有的相互独立的内存空间,工作内存中有主内存中的变量,工作内存中存储的是共享变量的“分身”;

  • JMM的工作流程
    工作内存不能对主内存的对象进行直接的操作。
    首先经过内存读操作获取到“分身”;再对“分身”进行业务处理;最后把结果通过写操作将“分身”写回主内存的“ 本体“。这是一次完整过程。

  • JMM存在的问题
    因为存在着先读再处理最后写回的过程,就会出现 线程A读取后,处理中,写回前(可以假设成在写回主内存之前打了个断点)的时候,线程B从主内存进行读操作(读到此处停下来想一下这个场景)。这样线程A和线程B的变量内容会不一样。

  • *解决办法
    首先考虑上同步锁synchronized,但是会影响程序性能,除此之外,就是使用本文的主角:volatile关键字

  • volatile关键字的主要特性之一:保证可见性
    volatile最重要的特性之一就是保证了volatile修饰的变量对所有线程的可见性
    可见性的意思就是:
    当一个线程修改了变量的值,新的值会立刻同步到主内存当中。而其他线程读取这个变量的时候,也会从主内存中拉取最新的变量值。
    使用了volatile修饰的变量,会遵循先行发生原则,以上述例子来说,就是保证了线程B从主内存读取变量的动作,一定后发生于线程A写入主内存的动作
    注意:
    volatile只保证变量的可见性,并不能保证变量的原子性。这是因为volatile不能保证对变量的操作是原子性的,例如i++。

  • volatile关键字的主要特性之二:阻止指令重排
    指令重排的意思是:JVM在编译Java代码的时候,或者CPU在执行JVM字节码的时候,对现有的指令顺序进行重新排序
    指令重排的目的是为了在不改变单线程下程序执行结果的前提下,优化程序的运行效率
    但是在多线程的情况下,会影响程序的执行结果。使用volatile关键字则可以避免这种情况。如何做到的呢?是通过CPU指令:”内存屏障“解决的
    内存屏障包括了四种类型:
    LoadLoad屏障(读完再读)、StoreStore屏障(写完再写)、LoadStore屏障(读完再写)、StoreLoad屏障(写完再读)。
    在一个变量被volatile修饰后,JVM会为我们做两件事:
    1.在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障。
    2.在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障。

  • volatile关键字的其他特性:解决了long类型和double类型数据的8字节赋值问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值