JMM规范 和 MESI 协议

JMM规范

JMM(Java 内存模型 Java)是一种抽象的概念,并不是真实存在的,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段、静态字段和构成数组对象的元素)的访问方式。Java内存模型中规定所有变量都存储在主存,主存是共享内存区域,所有线程都可以访问,但线程对变量的操作(读取赋值等)必须在工作内存中进行,首先要将变量从主存拷贝到自己的工作内存空间,然后对变量进行操作,操作完成后再将变量写回主存,不能直接操作主存中的变量,工作内存中存储着主存中的变量副本拷贝,而工作内存是每个线程的私有数据区域,因此不同的线程间无法访问对方的工作内存,线程间的通信(传值)必须通过主存来完成。

JMM 和 JVM 内存区域模型的区别:JMM 与 JVM 内存区域的划分是不同的概念层次,JMM描述的是一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式,JMM是围绕原子性,有序性、可见性展开。JMM与Java内存区域唯一相似点,都存在共享数据区域和私有数据区域,在JMM中主存属于共享数据区域,从某个程度上讲应该包括了堆和方法区,而工作内存数据线程私有数据区域,从某个程度上讲则应该包括程序计数器、虚拟机栈以及本地方法栈。

为了解决数据同步的问题,JMM 定义了数据同步的八大原子操作:

(1)lock(锁定):作用于主内存的变量,把一个变量标记为一条线程独占状态

(2)unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定

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

(4)load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中

(5)use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎

(6)assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量

(7)store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作

(8)write(写入):作用于工作内存的变量,它把store操作从工作内存中的一个变量的值传送到主内存的变量中

如果要把一个变量从主内存中复制到工作内存中,就需要按顺序地执行read和load操作,如果把变量从工作内存中同步到主内存中,就需要按顺序地执行store和write操作。但Java内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。

JMM 通过synchronized和 Lock的方式实现原子性,volatile关键字保证可见性,synchronized和lock也可以保证可见性。Java 内存模型具备一些先天的“有序性”,不需要通过任何手段就可以保证有序性,这个通常被称为 happens-before原则。

MESI协议

CUP与主内存交互协议 MESI 缓存一致性协议:MESI解决缓存一致性的问题,MESI是四个单词的首字母,即

  1. M(modifide)cacheline 有效 修改 将数据修改后缓存行中的数据就会失效

  2. E(exclusive)cacheline 有效 独占

  3. S (shard) cacheline 有效 共享 监听主内存数据修改

  4. I(Invalid) cacheline 无效

MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值