视频课程
小黑屋思过中,禁止观看!
评论并刷新后可见

您需要在视频最下面评论并刷新后,方可查看完整视频

视频课程
立即观看
付费视频

您支付费用,方可查看完整视频

¥{{user.role.value}}
课程视频
开始学习
会员专享

视频合集

Java内存模型深度剖析

  • 课程笔记
  • 问答交流

上一节课并发编程的发展历程谈到了单进程计算机–>多进程的计算机(操作系统)–>多线程的计算机–>纤程。

整个发展的主旋律会围绕:操作系统与CPU等硬件的发展。

随着CPU和高速内存的发展,会造成数据的不一致性的问题,就不得不谈到今天的内存模型,而Java内存模型属于用Java语言来实现的一种内存模型。

为了助大家掌握好内存模型,本节课我会重点讲解以下7点:

1.CPU和高速缓存
2.硬件内存结构
3.缓存一致性
4.指令重排
5.并发问题总结
6.Java内存模型组成
7.Java内存模型实现

我先从CPU和高速缓存谈起。

CPU和高速缓存

计算机处理器处理绝大多数运行任务都不可能只靠处理器“计算”就能完成,处理器至少需要与内存交互,如读取运算数据、存储运算结果,无法仅靠寄存器完成所有运算任务。

随着CPU技术的发展,CPU的执行速度越来越快,但是内存的技术并没有太大的改进。

由于计算机的存储设备与处理器的运算速度有几个数量级的差距,为了避免处理器等待缓慢的内存读写操作完成,现代计算机系统通过加入一层读写速度尽可能接近处理器运算速度的高速缓存。

缓存作为内存和处理器之间的缓冲,将运算需要使用到的数据复制到缓存中,让运算能快速运行,当运算结束后再从缓存同步回内存之中。

现在cpu和内存的交互大致如下:

Java内存模型深度剖析-mikechen

硬件内存架构

随着CPU能力的不断提升,一层缓存就慢慢的无法满足要求了,就逐渐的衍生出多级缓存。

CPU缓存可以分为:

1. 一级缓存(L1)
2. 二级缓存(L2)
3. 三级缓存(L3)

Java内存模型深度剖析-mikechen
加入了多级缓存,程序执行路径变为:

  1. 当CPU要读取一个数据时,首先从一级缓存中查找
  2. 如果没有找到再从二级缓存中查找
  3. 如果还是没有就从三级缓存或内存中查找

在多核cpu中,每个处理器都有各自的高速缓存(L1,L2,L3),而主内存确只有一个。

并发问题

1.缓存一致性协议

高速缓存的存储交互很好地解决了处理器与内存的速度矛盾,但是也为计算系统带来更高的复杂度,因为它引入了一个新的问题:缓存一致性(Cache Coherence)。
Java内存模型深度剖析-mikechen

 

评论交流
  1. JansenZhang

    java内存模型的三大特性是原子性、可见性以及有序性。在java中使用valatile关键字来实现可见性可有序性,使用synchronized关键字实现原子性。其中volatile实现的可见性和有序性是靠底层的内存屏障来做的,内存屏障主要做两件事,一是让内存屏障指令前后的指令不允许重排,这样就保证了有序性;二是让store操作的工作内存中的变量值立即刷新到主内存中,并通知其他线程工作内存中的该变量无效,需要重新获取,从而保证了可见性。而synchronized主要是通过monitorenter和monitorexit指令来保证同一时间只有一个线程能进入synchronized的代码块,从而保证了原子性。

    • mikechen

      重点都抓住了,一般synchronized会重点谈到:同步方法(ACC)与同步代码块(monitorenter和monitorexit)两个点,其实都是基于monitor对象监视器。

  2. 路正银

    问题出现的背景:现在多CPU(单内存)环境会出现缓存一致性的问题(原子性和可见性是为了解决这个问题的)
    编译器为了提高硬件效率,会对指令进行重排(有序性是为了解决这个问题)

    1、原子性
    此操作是不可分割的,不可中断,要么全部执行,要么全部不执行。特性的重点在于不可中断。
    java的实现:java内存模型提供了lock和unlock操作来满足这种需求。
    2、可见性
    当一个线程修改了共享变量的值。其他线程能够立即得知这个修改。
    java内存模型的实现:
    变量读取前从主内存刷新,变量修改后将新值同步回主内存,用主内存作为传输媒介。
    volatile(内存屏蔽)
    synchronized(加锁前清空工作内存中共享变量的值,用的时候实时从主内存获取,解锁之前,先把共享变量的值同步回主内存)
    final
    3、有序性
    是为了解决多线程环境下指令重排可能出现问题的情况(单线程环境先不会有问题,多线程环境下会出问题)
    java的实现:volatile(禁止指令重排序)
    synchronized(持有同一个锁的两个同步块只能串行的进入,相当于单线程)

  3. mikechen

    ✗棒棒的✗ 重点都抓住了,剩余就是细节部分,比如:除了Synchronized还有哪些可以解决原子性,以及各自的优劣势,可见性以及有序性的细节问题了,这些细节都掌握了,基本JMM的最核心的3大特征(并发编程三要素),基本就掌握了。

  4. 李鸿翼

    1.原子性
    在java中提供了两个高级的字节码指令monitorenter和monitorexit,使用对应的关键字Synchronized来保证代码块内的操作是原子的

    2.可见性
    volatile关键字(缓存一致性协议) Happens-Before规则

    3.有序性
    volatile关键字(内存屏障 禁止指令重排)
    synchronized关键字保证同一时刻只允许一个线程的操作