java并发编程--01(CPU缓存,Java内存模型)

目录

1.CPU缓存    

2.java内存模型

3.java并发的优势与风险


知识点结构
 

1.CPU缓存    

     

  1. 1为什么需要CPU cache?

       CPU的频率太快了,快到主存跟不上,这样在处理器时钟周期内,CPU常常需要等待主存,浪费资源,所 以cache的出现,是为了缓解CPU和内存之间速度的不匹配问题(结构:cpu->cache->memort),减少CPU读取主存的次数。

  1. 2CPU cache有什么意义?

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

  1. 3 缓存一致性(MESI)

CPU中每个缓存行使用四种状态进行标记
M:Modified 修改
指的是该缓存行只被缓存在该CPU缓存中,并且是被修改过的,因此他与主存的数据是不一致的,该缓存行中的数据需要在未来的某个时间点(允许其他CPU读取主存相应的内容之前)写回主存,然后状态变成E(独享)。

E :Exclusive 独享
缓存行只被缓存在该CPU的缓存中,是未被修改过的,与主存的数据是一致的,可以在任何时刻当有其他CPU读取该内存时,变成S(共享)状态,当CPU修改缓存行的内容时,变成M(修改)的状态。

S :Share 共享
意味着该缓存行可能被多个CPU进行缓存,并且该缓存中的数据与主存数据是一致的,当有一个CPU修改该缓存行时,其他CPU是可以被作废的,变成I(无效的)。

I :Invalid 无效的

代表这个缓存是无效的,可能是有其他CPU修改了该缓存行。

对应的四个操作
local read:读本地缓存
local write:写本地缓存
remote read:将内存中的数据读取过来
remote write:将数据写回主存

MESI数据状态有四种,引起数据状态的转换的CPU cahe操作也有四种

      在一个典型的多核系统中,每一个核都会有自己的缓存来共享总线,每一个CPU会发出读写(I/O)请求,而缓存的目的是为了减少CPU读写共享主存的次数;
一个缓存除了在无效(Invalid)状态,都可以满足CPU的读请求,一个无效(Invalid)的缓存行必须从主存中读取(变成Share或者Exclusive状态)来满足该CPU的读请求。
一个写请求只有在该缓存行是修改(Modified)或者独享(Exclusive)状态时才能被执行,如果缓存行处于共享(Share)状态,必须先将其他缓存中该缓存行变成无效(Invalid)状态(也即是不允许不同CPU同时修改同一缓存行,即使修改该缓存行中的不同数据也不允许)。该操作经常作用广播的方式来完成,例如:Request For Ownership(RFO)。
缓存可以随时将一个非修改(Modified)状态的缓存行作废,或者变成无效(Invalid)状态,而一个修改(Modified)状态的缓存行必须先被写回主存。
一个处于共享(Share)状态的缓存行业必须监听其他缓存使该缓存行无效或者独享该缓存行的请求,并将改缓存行变成无效(Invalid)。
一个处于独享(Exclusive )状态的缓存行也必须监听其他缓存读主存中该缓存行的操作,一旦有这种操作,该缓存行需要变成共享(Share)状态。
对于修改(Modified)和独享(Exclusive)状态而言总是精确的,他们在和该缓存行的真正状态是一致的。而共享(Share)状态可能是非一致的,如果一个缓存将处于共享(Share)状态的缓存行作废了,而另一个缓存实际上可能已经独享了该缓存行,但是该缓存却不会将该缓存行升迁为独享(Exclusive)状态,这是因为其他缓存不会广播他们作废掉该缓存行的通知,同样由于缓存并没有保存该缓存行的copy的数量,因此也没有办法确定自己是否已经独享(Share了该缓存行)。
从上面的意义看来独享(Exclusive)状态时一种投机性的优化:如果一个CPU想修改一个处于共享(Share)状态的缓存航,总线事务需要将所有缓存行的copy变成Invalid状态,而修改独享(Exclusive)状态的缓存不需要使用总线事务。

  •    1.4乱序执行优化

2.java内存模型

     java内存模型(Java Memory Model,JMM)是java虚拟机规范定义的,用来屏蔽掉java程序在各种不同的硬件和操作系统对内存的访问的差异,这样就可以实现java程序在各种不同的平台上都能达到内存访问的一致性。需要区分一下java内存模型和JVM内存模型。

    java内存模型主要目标是定义程序中变量的访问规则,规定一个线程如何和何时可以看到一个其他线程修改过的变量,在必须时如何同步访问java共享变量。

  •  2.1 java内存模型

     

   看图可知线程栈内存,也就是他的工作内存存放的是私有的变量,而堆内存上主要存放对象,他们的生命周期,访问速度都是不一样的。基本类型,本地变量都存在栈上面,对象都存在堆上,读取的速度也不一样,生命周期也不一样,如果两个线程同时访问一个对象的成员变量,那么两个线程栈上会存有这个对象成员变量的私有拷贝。需要理解下面两个概念:

   主内存:java虚拟机规定所有的变量(不是程序中的变量)都必须在主内存中产生,为了方便理解,可以认为是堆区。然而两者并没有任何关系,可以与前面说的物理机的主内存相比,只不过物理机的主内存是整个机器的内存,而虚拟机的主内存是虚拟机内存中的一部分。

  工作内存: java虚拟机中每个线程都有自己的工作内存,该内存是线程私有的为了方便理解,可以认为是虚拟机栈。可以与前面说的高速缓存相比。线程的工作内存保存了线程需要的变量在主内存中的副本。虚拟机规定,线程对主内存变量的修改必须在线程的工作内存中进行,不能直接读写主内存中的变量。不同的线程之间也不能相互访问对方的工作内存。如果线程之间需要传递变量的值,必须通过主内存来作为中介进行传递。

  • 2.2Java主存架构与物理硬件架构之间的关系

 从这个图可以看出来,工作内存存的是主存中变量的拷贝,他由寄存器,CPU缓存和主内存构成。

  •  2.3同步操作与所对应的规则

lock(锁定):作用于主内存的变量,一个变量在同一时间只能一个线程锁定,该操作表示这条线成独占这个变量

unlock(解锁):作用于主内存的变量,表示这个变量的状态由处于锁定状态被释放,这样其他线程才能对该变量进行锁定

read(读取):作用于主内存变量,表示把一个主内存变量的值传输到线程的工作内存,以便随后的load操作使用

load(载入):作用于线程的工作内存的变量,表示把read操作从主内存中读取的变量的值放到工作内存的变量副本中(副本是相对于主内存的变量而言的)

use(使用):作用于线程的工作内存中的变量,表示把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个需要使用变量的值的字节码指令时就会执行该操作

assign(赋值):作用于线程的工作内存的变量,表示把执行引擎返回的结果赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的字节码指令时就会执行该操作

store(存储):作用于线程的工作内存中的变量,把工作内存中的一个变量的值传递给主内存,以便随后的write操作使用

write(写入):作用于主内存的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中

      如果要把一个变量从主内存传输到工作内存,那就要顺序的执行read和load操作,如果要把一个变量从工作内存回写到主内存,就要顺序的执行store和write操作。对于普通变量,虚拟机只是要求顺序的执行,并没有要求连续的执行,所以如下也是正确的。对于这8中操作,虚拟机也规定了一系列规则,在执行这8中操作的时候必须遵循如下的规则:

不允许read和load、store和write操作之一单独出现,也就是不允许从主内存读取了变量的值但是工作内存不接收的情况,或者不允许从工作内存将变量的值回写到主内存但是主内存不接收的情况

不允许一个线程丢弃最近的assign操作,也就是不允许线程在自己的工作线程中修改了变量的值却不同步/回写到主内存

不允许一个线程回写没有修改的变量到主内存,也就是如果线程工作内存中变量没有发生过任何assign操作,是不允许将该变量的值回写到主内存

变量只能在主内存中产生,不允许在工作内存中直接使用一个未被初始化的变量,也就是没有执行load或者assign操作。也就是说在执行use、store之前必须对相同的变量执行了load、assign操作

一个变量在同一时刻只能被一个线程对其进行lock操作,也就是说一个线程一旦对一个变量加锁后,在该线程没有释放掉锁之前,其他线程是不能对其加锁的,但是同一个线程对一个变量加锁后,可以继续加锁,同时在释放锁的时候释放锁次数必须和加锁次数相同。

对变量执行lock操作,就会清空工作空间该变量的值,执行引擎使用这个变量之前,需要重新load或者assign操作初始化变量的值

不允许对没有lock的变量执行unlock操作,如果一个变量没有被lock操作,那也不能对其执行unlock操作,当然一个线程也不能对被其他线程lock的变量执行unlock操作

对一个变量执行unlock之前,必须先把变量同步回主内存中,也就是执行store和write操作

当然,最重要的还是如开始所说,这8个动作必须是原子的,不可分割的。

3.java并发的优势与风险

并发的优势与风险:

参考文章:

https://blog.csdn.net/f191501223/article/details/84310300

https://www.jianshu.com/p/15106e9c4bf3

发布了217 篇原创文章 · 获赞 70 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_37650458/article/details/102870122