• 什么是Java内存模型中的happens-before


    Java内存模型JMM

      Java内存模型(即Java Memory Model , 简称JMM),本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序个各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式

      

    由于JVM运行时程序的实体是线程,而每个线程创建时,而JVM都会为其创建一个工作内存,有一些地方叫做栈空间,用于存储线程私有的数据,而Java内存模型中规定所有的变量都保存在主内存中,主内存是共享内存区域,所以线程都可以访问。但线程对变量的操作,则读取和赋值等,必须在工作内存中进行。首先从主内存中拷贝变量到工作内存中,然后对变量进行操作,操作完成后,再将变量写回到主内存中。注意:线程是不能直接操作主内存的变量,工作内存中就存在主内存变量的副本。因此每个线程都不能互相访问对方的工作内存,所以线程之间的通信必须通过主内存去进行通信。

    JMM中的住内存和工作内存

    JVM中的主内存

      1、存储Java实例对象

      2、包括成员变量、类信息、常量、静态变量等

      3、属于数据共享的区域,多线程并发操作时会引发线程安全问题

      

    JVM中的工作内存

      1、存储当前方法的所有本地变量信息,本地变量对其他线程不可见

      2、字节码行号指示器Native方法信息

      3、属于线程私有数据区域,不存线程安全问题

    JMM与Java内存区域划分是不同的概念层

      1、JMM描述的是一组规则,围绕原子性,有序性,可见性展开

      2、相似点:存在共享区域和私有区域

    主内存与工作内存的数据存储类型以及操作方式归纳

      1、方法里的基本数据类型本地变量将直接存储在工作内存的栈帧结构

      2、引用类型的本地变量:引用存储在工作内存中实例存储在主内存中

      3、成员变量、static变量、类信息均会被存储在主内存中

      4、主内存共享的方式是线程各拷贝一份数据到工作内存,操作完成后刷新回主内存

    指令重排序需要满足的条件

      1、在单线程环境下不能改变程序运行的结果

      2、存在数据依赖关系的不允许重排序

      无法通过happens-before原则推导出来的,才能进行指令的重排序

    A操作的结果需要对B操作可见,则A与B存在happens-before关系

    volatile : JVM提供的轻量级同步机制

      1、保证被volatile修饰的共享变量对所有线程总是可见的

      2、禁止指令重排序优化

    volatile的可见性

      1、注意,不是线程安全的,只是可见

    另外一种写法:

    volatile变量为何立即可见?

      1、当些一个volatile变量时,JMM会把该线程对应的工作内存中的共享变量值刷新到主内存中

      2、当读取一个volatile变量时,JMM会把该线程对应的工作内存设置为无效

    volatile如何禁止重排优化

      内存屏障

      1、保证特定操作的执行顺序

      2、保证某些变量的内存可见性

      通过插入内存屏障指令禁止在内存屏障前后的指令执行重排序优化

      强制刷出各种cpu的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本

    上面的操作,看上去没有问题,但是还是有隐患,有可能会有指令重排序之后,导致的问题。

  • 相关阅读:
    WinScan2PDF ----将图片批量选中后转换成pdf
    画质王(iCYPlayer)播放器
    如何让UEFI BIOS主板在Windows XP SP3 32位系统下识别GPT格式移动硬盘
    windows xp 文件排列全部默认以“详细信息”显示
    asus 笔记本从window 7系统安装到window xp系统的过程
    FastCopy --- 快速复制文件工具
    《极地》纪录片
    Android 机器全擦之后无法驻网了,如何备份和恢复QCN?
    Google Camera
    Android 命令行工具-apkanalyzer
  • 原文地址:https://www.cnblogs.com/vingLiu/p/10677428.html
Copyright © 2020-2023  润新知