JMM内存相关知识

115 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第9天,点击查看活动详情

硬件上的内存模型

image.png

计算机在执行程序的时候,指令都是在CPU中执行的,执行指令的过程需要涉及到读写数据,CPU的读写是很快的,内存的读写没有CPU读写快,如果让cpu和内存直接交互的话内存就是性能的瓶颈,于是乎就引入了一个缓存内存的概念。

image.png

如果是单条指令执行这个模型是没有问题的,如果是多个一起执行的话,就会导致一些问题(原本改引用的结果变成了初始的值),这个时候就引入了缓存一致性协议

image.png

JMM

image.png

Java Memory Model(java内存模型),也是一种规范,是个抽象模型

  • 定义了JVM在计算机内存(RAM)中的工作方式
  • 定义了主内存与线程工作内存之间的关系,类似于硬件层面上,内存和CPU的关系
  • 线程工作内存并不是物理存在的,实现方式包括硬件的高速缓存,寄存器或是编译机优化。

JMM8大原子操作

image.png

  • lock:标识一个变量为线程独占
  • unlock:释放一个变量的线程独占状态
  • read:把变量值从主内存传输到工作内存
  • load:把read的值给变量副本
  • use:执行引擎使用变量的值
  • assign:将执行引擎收到的值放入变量副本
  • store:把变量值从工作内存传输到主内存
  • write:把store的值给变量

并发编程三大要素

  • 原子性:一个或一组操作是不可分隔的原子,不能打断
    • 可以通过synchronized和一些lock来保证
  • 可见行:一个线程修改变量后,立即能被另一个线程观测到
    • volatile关键字要求变量被修改后立即同步到主内存,每次使用时也必须从主内存读取
    • synchronized保证,在加锁前清空工作内存的变量值,从主内存重新读取,在释放锁前把工作内存变量刷新回主内存
  • 有序性:程序的执行顺序,对线程外部来说,是固定且可预期的
    • synchronized能够保证代码层面,对线程外部的有序性
    • volatile则能够防止指令重排序

指令重排序

在执行指令时,出于提高性能等原因,编译器,处理器会改变指令的执行顺序

  • 重排序不能改变程序在单线程下的执行结果(as-if-serial原则)
  • 不会对存在依赖关系的指令进行重排序(happens-before原则)