可见性

作者: 文刀雨 | 来源:发表于2021-03-17 23:49 被阅读0次

导致共享变量在线程间不可见的原因

  • 线程交叉执行
  • 重排序结合线程交叉执行
  • 共享变量更新后的值没有在工作内存与主内存间及时更新

synchronized

JMM关于synchronized的两条规定:

  • 线程解锁前,必须把共享变量的最新值刷新到主内存
  • 线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值(注意,加锁与解锁是同一把锁)

volatile

通过加入内存屏障禁止重排序 优化来实现

  • 对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量值刷新到主内存
  • 对volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量


    可见性 - volatile写.png
    可见性 - volatile读.png

volatile 适合作为状态标记量

有序性

Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
volatile synchronized lock

有序性- happens-before 原则

  • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
  • 锁定规则: 一个unLock操作先行发生于后面对同一个锁的lock操作
  • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
  • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
  • 线程启动规则:Thread对象的start()方法先行发生于此线程的每一个动作
  • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。
  • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束,Thread.isAlive()的返回值手段检测到线程已经终止执行
  • 对象终结规则:一个对象的初始化完成先行发生于他的finalized()方法的开始

原子性:Atomic包,CAS算法,synchronized, Lock
可见性:synchronized,volatile
有序性:happens-before

相关文章

  • 见性见性见性

    人活着活着就迷失了忘记了自己是谁迷失了本性,活着活着想死了。 其实是没有见性,人如何见性,见什么性得通过人生经历来...

  • 多线程 | Volatile到底有什么用?

    Volatile的作用: 保持内存可见性.内存可见性:多个线程操作同一个变量,可确保写线程更新变量,其他读线程可以...

  • 美好生活排行榜|酒桌即中国

    酒精不燃烧,不算搞社交。 喝酒可大俗可大雅,可论国是可谈风月,可攀交情可见性情,可怡情可乱性,可养生可伤身,可豪饮...

  • 并发编程-synchronized关键字大总结

    0、synchronized 的特点: 可以保证代码的原子性和可见性。 1、synchronized 的性质: 可...

  • 第三章——对象的共享

    3.1 可见性 3.1.3 加锁与可见性 内置锁可以用于确保某个线程以一种可预测的方法来查看另一个线程的执行结果。...

  • 《自我边界》之可预见性

    对某些人来说,“边界”让他们明确了路标,而对另一些人而言,“边界”让他们在之前提到的树上爬得更高,对自己和周围的世...

  • 02|Java内存模型

    可见性、原子性、有序性是并发问题的三个关键因素。 可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到。 可...

  • 何为明心见性?如何塑梦圆梦?

    何为明心见性?如何塑梦圆梦? ----明心见性,自性具足;净心圆梦,觉悟人民。 何为明心见性?如何明心见性? 明心...

  • solidity-4.可见性

    可见性或权限控制(Visibility And Accessors) 可见性 external 外部可见性可以被其...

  • 【Java进阶】并发编程

    . 概述 三种性质 可见性:一个线程对共享变量的修改,另一个线程能立刻看到。缓存可导致可见性问题。 原子性:一个或...

网友评论

      本文标题:可见性

      本文链接:https://www.haomeiwen.com/subject/nsqpyktx.html