JMM的介绍

什么是JMM以及解决什么问题

JMM最初由JSR-133(Java Memory Model and Thread Specification)文档描述,JMM定义了一组规则或规范,该规范定义了一个线程对共享变量写入时,如何确保对另一个线程是可见的。实际上,JMM提供了合理的禁用缓存以及禁止重排序的方法,所以其核心的价值在于解决可见性和有序性。

Java内存模型:
  • 主存:

    主要存储Java实例对象,所有线程创建的实例对象都存放在主存中,无论该实例对象是成员变量还是方法中的本地变量(也称局部变量),当然也包括共享的类信息、常量、静态变量。

  • 工作内存:

    主要存储当前方法的所有本地变量信息(工作内存中存储着主存中的变量副本),每个线程只能访问自己的工作内存,因此不存在线程安全问题。
    在这里插入图片描述

解决的问题

主要解决代码重排序和缓存可见性问题。

怎么解决的

JMM提供的方案包括大家都很熟悉的volatile、synchronized、final等。

JMM的8个指令

在这里插入图片描述

如果要把一个变量从主存复制到工作内存,就要按顺序执行Read和Load操作;如果要把变量从工作内存同步回主存,就要按顺序执行Store和Write操作。

说明:

  • 其中Read和Load、Store和Write是必须有序,但是并不需要连续;不能单独出现一个指令
  • 一个变量同一时刻只能被一个线程执行lock,但是同一个线程可以执行多次lock,多次lock,意味着只能执行相同次的unlock才能解锁。
解决有序性

提供内存指令,JVM编译器实现这些指令,禁止特定类型的编译器和CPU重排序。

JMM内存屏障主要有Load和Store两类:

  • Load Barrier(读屏障)

    在读指令前插入读屏障,可以让高速缓存中的数据失效,重新从主存加载数据。

  • Store Barrier(写屏障)

    在写指令之后插入写屏障,能让写入缓存的最新数据写回主存。

实际对Load Barrier和Store Barrier进行组合,用于禁止特定类型的CPU重排序。

  • LoadLoad(LL)屏障

    Load1; LoadLoad; Load2;
    

    该示例的含义为:在Load2要读取的数据被访问前,使用LoadLoad屏障保证Load1要读取的数据被读取完毕。

  • StoreStore(SS)屏障

    Store1; StoreStore; Store2;
    

    该示例的含义为:在Store2及后续写入操作执行前,使StoreStore屏障保证Store1的写入结果对其他CPU可见。

  • LoadStore(LS)屏障

    Load1; LoadStore; Store2;
    

    该示例的含义为:在Store2及后续写入操作执行前,使LoadStore屏障保证Load1要读取的数据被读取完毕。

  • StoreLoad(SL)屏障

    Store1; StoreLoad; Load2;
    

    该示例的含义为:在Load2及后续所有读取操作执行前,使StoreLoad屏障保证Store1的写入对所有CPU可见。

volatile是怎么解决问题的
  • 在每个volatile读操作的后面插入一个LoadLoad屏障。
  • 在每个volatile读操作的后面插入一个LoadStore屏障。
  • 在每个volatile写操作的前面插入一个StoreStore屏障。
  • 在每个volatile写操作的后面插入一个StoreLoad屏障。
    在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值