专题1-3-java内存模型JMM

1 概念介绍

        JMM是java为了解决多线程通过对共享内存进行通信时存在的本地内存数据不一致问题(可见性问题)、编译器会对代码指令重排序(有序性问题)、处理器会对代码乱序执行(原子性问题)等问题的一种规范。java虚拟机(JVM)由硬件发展而来,JMM也是由计算内存模型发展而来的。

2 计算机内存模型

2.1 CPU直接读取阶段

       最初阶段,CPU的处理速度和内存的读写速度相匹配,所以CPU直接从内存中读取数据没有问题。

2.2 CPU读取单个缓存

       CPU处理技术在不断地发展,内存的技术并没有多大变化,从内存中读取数据的速度远远跟不上CPU的处理速度,因此在CPU和内存之间引入了高速缓存。它的特点是速度快,内存小并且昂贵。

2.3 CPU读取多级缓存

       随着技术的发展,缓存变成了多级缓存,CPU也得到了发展,由单核变成了多核。单核CPU只含有一套L1,L2,L3缓存;如果CPU含有多个核心,即多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存。当CPU要读取一个数据时,首先从一级缓存中查找,如果没有找到再从二级缓存中查找,如果还是没有就从三级缓存或内存中查找。

2.4 存在问题

(1)缓存一致性问题

       单线程。cpu核心的缓存只被一个线程访问。缓存独占,不会出现访问冲突等问题。

       单核CPU,多线程。进程中的多个线程会同时访问进程中的共享数据,CPU将某块内存加载到缓存后,不同线程在访问相同的物理地址的时候,都会映射到相同的缓存位置,这样即使发生线程的切换,缓存仍然不会失效。但由于任何时刻只能有一个线程在执行,因此不会出现缓存访问冲突。

        多核CPU,多线程。每个核都至少有一个L1 缓存。多个线程访问进程中的某个共享内存,且这多个线程分别在不同的核心上执行,则每个核心都会在各自的caehe中保留一份共享内存的缓冲。由于多核是可以并行的,可能会出现多个线程同时写各自的缓存的情况,而各自的cache之间的数据就有可能不同。

       在CPU和主存之间增加缓存,在多线程场景下就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致。

(2)处理器优化和指令重排

       为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理。这就是处理器优化。Java虚拟机的即时编译器(JIT)也会做指令重排。我们的代码顺序被打乱,指令被重排,就可能不会按照我们的意愿去执行了。

       内存模型解决并发问题主要采用两种方式:限制处理器优化和使用内存屏障。

3  java内存模型JMM

       java内存模型在计算机内存模型下发展而来,它和计算机内存模型极为相似。所以也存在缓存一致性问题和指令重排问题,其中指令重排的过程如下图所示

JVM为了解决这些问题提出来JMM模型,结构如下:

 

(1)模型规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存,线程的工作内存中保存了该线程中用到的变量的主内存副本拷贝。

(2)线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存。

(3)不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量的传递均需要自己的工作内存和主内存之间进行数据同步进行。

      通过这个模型解决了多线程下多核CPU的缓存一致性问题(可见性)。Java中的volatile关键字提供了一个功能,那就是被其修饰的变量在被修改后可以立即同步到主内存,被其修饰的变量在每次使用之前都从主内存刷新。因此,可以使用volatile来保证多线程操作时变量的可见性。除volatile,Java中的synchronized和final两个关键字也可以实现可见性。

      由于编译器指令重排带来的问题(原子性,有序性),Java中可以使synchronized和和volatile来保证方法和代码块内的操作是有序性。synchronized来保证操作的原子性。volatile关键字会禁止指令重排。synchronized关键字保证同一时刻只允许一条线程操作。

博客地址:

https://blog.csdn.net/renchunlin66

码云社区地址:

https://gitee.com/renchunlin66

公众号请搜索:“快乐的一只”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值