上一节课Java并发编程的发展历程谈到了单进程计算机–>多进程的计算机(操作系统)–>多线程的计算机–>纤程。
整个发展的主旋律会围绕:操作系统与CPU等硬件的发展。
随着CPU和高速内存的发展,会造成数据的不一致性的问题,就不得不谈到今天的内存模型,而Java内存模型属于用Java语言来实现的一种内存模型。
本节课Java内存模型重点讲到以下7个知识点:
1.CPU和高速缓存
2.硬件内存结构
3.缓存一致性
4.指令重排
5.并发问题总结
6.Java内存模型组成
7.Java内存模型实现
我先从CPU和高速缓存谈起。
CPU和高速缓存
计算机处理器处理绝大多数运行任务都不可能只靠处理器“计算”就能完成,处理器至少需要与内存交互,如读取运算数据、存储运算结果,无法仅靠寄存器完成所有运算任务。
随着CPU技术的发展,CPU的执行速度越来越快,但是内存的技术并没有太大的改进。
由于计算机的存储设备与处理器的运算速度有几个数量级的差距,为了避免处理器等待缓慢的内存读写操作完成,现代计算机系统通过加入一层读写速度尽可能接近处理器运算速度的高速缓存。
缓存作为内存和处理器之间的缓冲,将运算需要使用到的数据复制到缓存中,让运算能快速运行,当运算结束后再从缓存同步回内存之中。
现在cpu和内存的交互大致如下:
硬件内存架构
随着CPU能力的不断提升,一层缓存就慢慢的无法满足要求了,就逐渐的衍生出多级缓存。
CPU缓存可以分为:
1. 一级缓存(L1)
2. 二级缓存(L2)
3. 三级缓存(L3)
加入了多级缓存,程序执行路径变为:
- 当CPU要读取一个数据时,首先从一级缓存中查找
- 如果没有找到再从二级缓存中查找
- 如果还是没有就从三级缓存或内存中查找
在多核cpu中,每个处理器都有各自的高速缓存(L1,L2,L3),而主内存确只有一个。
课后作业
这就是今天的全部内容,留一道Java内存模型经常考察的面试题给你。
1.原子性
在java中提供了两个高级的字节码指令monitorenter和monitorexit,使用对应的关键字Synchronized来保证代码块内的操作是原子的
2.可见性
volatile关键字(缓存一致性协议) Happens-Before规则
3.有序性
volatile关键字(内存屏障 禁止指令重排)
synchronized关键字保证同一时刻只允许一个线程的操作
✗棒棒的✗ 重点都抓住了,剩余就是细节部分,比如:除了Synchronized还有哪些可以解决原子性,以及各自的优劣势,可见性以及有序性的细节问题了,这些细节都掌握了,基本JMM的最核心的3大特征(并发编程三要素),基本就掌握了。
问题出现的背景:现在多CPU(单内存)环境会出现缓存一致性的问题(原子性和可见性是为了解决这个问题的)
编译器为了提高硬件效率,会对指令进行重排(有序性是为了解决这个问题)
1、原子性
此操作是不可分割的,不可中断,要么全部执行,要么全部不执行。特性的重点在于不可中断。
java的实现:java内存模型提供了lock和unlock操作来满足这种需求。
2、可见性
当一个线程修改了共享变量的值。其他线程能够立即得知这个修改。
java内存模型的实现:
变量读取前从主内存刷新,变量修改后将新值同步回主内存,用主内存作为传输媒介。
volatile(内存屏蔽)
synchronized(加锁前清空工作内存中共享变量的值,用的时候实时从主内存获取,解锁之前,先把共享变量的值同步回主内存)
final
3、有序性
是为了解决多线程环境下指令重排可能出现问题的情况(单线程环境先不会有问题,多线程环境下会出问题)
java的实现:volatile(禁止指令重排序)
synchronized(持有同一个锁的两个同步块只能串行的进入,相当于单线程)
回答很全面 ✗咧嘴笑✗
java内存模型的三大特性是原子性、可见性以及有序性。在java中使用valatile关键字来实现可见性可有序性,使用synchronized关键字实现原子性。其中volatile实现的可见性和有序性是靠底层的内存屏障来做的,内存屏障主要做两件事,一是让内存屏障指令前后的指令不允许重排,这样就保证了有序性;二是让store操作的工作内存中的变量值立即刷新到主内存中,并通知其他线程工作内存中的该变量无效,需要重新获取,从而保证了可见性。而synchronized主要是通过monitorenter和monitorexit指令来保证同一时间只有一个线程能进入synchronized的代码块,从而保证了原子性。
Jansen加油,刚回来就看见你一下提交好几个作业 ✗咧嘴笑✗ ✗拳头✗ 挺好,输出是最好的学习 。
重点都抓住了,一般synchronized会重点谈到:同步方法(ACC)与同步代码块(monitorenter和monitorexit)两个点,其实都是基于monitor对象监视器。