• Volatile


    Volatile

    特性:保证可见性,防止指令重排,不保证原子性

    JMM

    三大特性:可见性、原子性、有序性

    八大原子操作

    read读取:将主内存中的变量加载到工作内存

    load加载:将工作内存中的数据赋给工作内存中的变量

    use操作:将赋值后的变量进行计算操作

    assign赋值:将计算后的数据赋给工作内存中的变量

    store存储:将赋值后的数据写回主内存

    write写入:将上一步主内存中的数据赋值给对应的变量

    lock加锁:将变量标记为线程独占状态

    unlock解锁:将加锁的标记解除

    lock和unlock介入时机

    被volatile修饰的对象在store之前会对主内存中变量加锁lock,加锁后其他线程将无法对主内存对应的变量进行操作,当持有锁执行完store和write后,会释放锁unlock。

    因为lock--unlock之间就是单纯的内存操作,所以速度非常快,几乎不影响性能。

    为什么可以保证可见性( MESI缓存一致性协议)

    例如:

    ​ 1. 定义一个变量 public volatile int i=0;

    ​ 2. A、B、C线程同时将i加载到工作内存中

    ​ 3. A线程完成了load操作;B线程完成了assign操作(i+1);C线程完成了store操作

    ​ 4. 当C线程完成store操作后,因为变量i是被volatile修饰的,所以会通过MESI协议分别通知 A线程和B线程,将AB线程中工作内存中的变量i进行失效(我理解为将i=null)

    ​ 5. 这时AB线程再继续操作的时候发现i=null了,就要去主内存中获取(read)新的值,这样 就保证了可见性

    其他相关信息:

    1. 在第五步,read时线程C还没完成unlock操作,那么线程会阻塞等待;

    2. 如果没有被volatile修饰,在执行完assign操作后,线程会继续执行后面业务的操 作,不确定什么时候才会将i变量调用storewrite写回主内存;如果被volatile修饰 了,即便后面还有很多业务流程,线程也不会去执行,线程会立刻执行storewrite 操作

    为什么不保证原子性

    在上面的例子中

    1. 初始状态下i=0
    2. ABC线程同时将i=0加载到工作内存中,而B线程完成了use操作(i+1),并且将1写回了工作内存中,这时B线程工作内存变量i值为1;
    3. C线程完成了store操作,并且完成write操作,此时主内存中变量i值由0变为1;

    并且通过MESI协议使AB线程工作内存中的变量i失效;

    1. 这时,线程B要执行store操作了,发现工作内存中的i失效了,便重新从主内存中读取一份,然后再执行store操作,但这时读取i的值为1,这个1是线程C计算得出的,而不是线程B计算得出的,丢失了B线程操作的记录

    以上,就是为什么volatile不保证原子性原因

    如何避免不保证原子性

    1. synchronized
    2. lock
    3. Atomic原子类

    防止指令重排

    例如:new 一个User对象 User user=new User();

    通过javap命令得到字节码文件可得知,new操作分为三步

    1. 在栈上创建内存
    2. 在堆中初始化对象
    3. 将栈和堆进行引用

    如果user没有volatile修饰,那么执行流程可能是123,132,312。。。。

    加上了修饰,只会是123.

    这个在单例模式中体现最为明显,如果不加修饰,可能会导致有引用,但为初始化,导致报错

    八个原子操作流程图

    read->load->use->assign->lock->store->write->unlock

    虚线嗅探机制为实时监听中。

    红色线表示不保证volatile原子性的阶段

    img

  • 相关阅读:
    剑指offer-正则表达式匹配-字符串-python****
    剑指offer-构建乘积数组-数组-python
    剑指offer-数组中重复的数字-数组-python
    剑指offer-孩子们的游戏(圆圈中最后剩下的数)-知识迁移能力-python
    剑指offer-扑克牌顺子-知识迁移能力-python
    剑指offer-左旋转字符串-知识迁移能力-python
    剑指offer-和为S的两个数字-知识迁移能力-python
    Shortest Path [3](25分)
    Topological Sort (25分)
    计算机系统基础(一):程序的表示、转换与链接(第十二周小测验)
  • 原文地址:https://www.cnblogs.com/rb2010/p/13396243.html
Copyright © 2020-2023  润新知