Loading

并发基础:Java内存模型

一.现代计算机的并发问题描述

1.什么是并发?

简单来说,并发就是多个线程“同时”运行。 假设一个程序中有多个线程,如果程序在单核处理器上运行,那么多个线程将交替地换入或者换出内存,每个线程都处于执行过程中地某个状态。如果运行在多核处理器上,此时,程序中的每个线程都将分配到一个处理器核中,因此可以同时运行。

2.什么是高并发?

高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常指通过设计保证系统能够 同时并行处理多个请求

3.并发存在的风险

现代的多CPU计算机已经普及,也就意味着有多Cache,并发时也就意味着存在着一定的风险:

现在我们要让计算机计算1+1-1的操作,计算机进行多核并发运算:

上面的计算可能会被分解成两个任务:对原始内存中1的加一操作和减一操作,如果这两个任务没有定义执行顺序,那么可能会发生下面的事情:

两个CPU同时从主存中读到同一个数据1存到各自的缓存中,然后各自对对它进行操作,CPU1将其加1结果2存到主存中,另一个CPU2将其减一结果0存到主存中,那么结果就可能变为 :如果是CPU1的存入执行先于2,那么最后结果为0,反之结果为2,它们都不是正确的结果,我们要的正确结果为1

这就是并发所带来的风险:影响结果的正确性,而结果的正确性在生产环境中是极为重要的!!!
在这里插入图片描述
对于CPU多缓存的并发数据安全问题,诞生了MESI协议,该协议用于保证多个CPU 缓存之间共享数据的一致性。

二.Java内存模型(JMM)

1.什么是JMM?

JMM规范了计算机内存与JVM如何协同工作的,它规定了一个线程如何和何时可以看到其他线程修改后的共享变量,以及如何同步的访问共享变量。

2.JMM主要分区

Heap区:主要对应于计算机的主存,存取速度慢,主要存放对象,静态成员变量。
Stack区:主要对应于计算机的缓存和cpu寄存器,存取速度快,存放基本类型变量,本地变量。

在这里插入图片描述

3.JMM规范

1)八种同步操作

lock, read, load ,use assign, store, write ,unlock
在这里插入图片描述

2)八种操作的同步规则

1.如果要把一个变量从主存中复制到工作内存中,就需要按顺序地执行read和load操作,反之,如果要把变量从工作内存中同步回主存中就要按顺序的执行store和write操作。(JMM只要求按顺序执行,没有规定必须连续,它们之间允许存在其他操作)

2.read和load,store和write必须成对出现

3.不允许一个线程丢弃它最近的assign操作,换句话说就是变量如果在工作内存中改变后必须同步到主存中

4.不允许一个线程没有原因的把数据从工作内存同步回主存中

5.新的变量只能在主存中产生,不允许工作内存中直接使用一个未load的变量

6.一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被一条线程重复执行多次,且lock和unlock必须成对

7.对一个主存中变量执行lock操作,JMM将会清空工作内存中此变量的此前的值,在执行引擎使用这个变量前需要重新执行load操作初始化变量的值

8.如果一个变量事先没有被lock锁定,则不允许对它执行unlock操作,也不允许去unlock一个被其他线程锁定的变量

9.对一个变量进行unlock操作执行,必须先把此变量同步到主存中

JMM从相对于底层的层面保证了数据安全。

三.CPU多级缓存

1.为什么需要CPU cache?

因为CPU的频率太快了,快到主存跟不上,这样在处理器时钟周期内,CPU常常需要等待主存,浪费资源。 所以cache的出现,是为了缓解CPU和内存之间速度不匹配的问题。(注意:是缓解,并不是解决了)

2.带有高速缓存的CPU执行计算的流程如下

1)程序以及数据被加载到主存
2)指令和数据被加载到CPU的高速缓存
3)CPU从高速缓存中得到数据执行指令,并把结果写到高速缓存中
4)高速缓存中的数据被写回主内存

3.CPU cache的意义

局部性原理:
1)时间局部性:如果某个数据被访问,那么在不久的将来,它很可能被再次访问。
2)空间局部性:如果某个数据被访问,那么与它相邻的数据很快也可能被访问。

4.CPU多级缓存的缓存一致性协议(MESI)

它用于保证多个Cpu cache之间缓存共享数据的一致。

目前流行的多级缓存结构如下:
在这里插入图片描述
我们很容易知道,多个CPU的情况下会有多个一级缓存,那么如何保证缓存内部数据的一致而不让系统数据混乱, MESI就是解决这个问题的。

1)MESI的含义: 它分别是由这个协议中描述缓存行的四个状态的首字母组成

状态描述
Modified(修改)该缓存行有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中
Exclusive(独享)该缓存行有效,数据和内存中的数据一致,数据只存在于本Cache中
Shared(共享)该缓存行有效,数据和内存中的数据一致 ,数据被多个Cache共享
Invalid(无效)该缓存行无效

2)MESI状态转换

在这里插入图片描述
触发事件:

触发事件描述
Local read本地cache读取本地cache数据
Local write本地cache写入本地cache数据
Remote read其他cache读取本地cache数据
Remote write其他cache写入本地cache数据

下图示意了当一个缓存行调整状态的时候,另外一个缓存行需要调整的状态:

在这里插入图片描述

5.乱序执行优化

1)什么是乱序执行优化?
处理器为了提高计算速度而做出违背代码原有顺序的优化。
单核时代处理器的乱序执行优化不会使预期的目标偏离,但是在多核时代并不会这样,如果我们不做一些防护措施,最后得出的结果会和我们预期的结果大不相同。

四.并发的优势和风险

1.优势

1)速度:并发程序可以同时处理多个请求,响应速度更快,且一些复杂的操作可以分成多个进程同时进行。
2)设计:运用并发技术我们在设计程序的时候在某些请况下变得更简单,也可以有更多的选择。
3)资源利用:并发程序可以极大的提高资源利用率。(例如CPU能够在等待IO的时候做一些其他计算)

2.风险

1)安全性问题:当多个线程共享数据时可能会发生期望偏离的结果。
2)活跃性问题:活跃性问题指的是线程中某些操作无法执行下去了,比如:发生死锁。
3)性能问题:线程过多时会使CPU频繁切换,调度时间增加,降低性能,以及消耗过多内存资源。

posted @ 2020-10-11 09:30  文牧之  阅读(11)  评论(0)    收藏  举报  来源