Java内存模型-JMM

木之本 桜 2022-4-5 27 4/5

Java内存模型(JMM)

我们常说的JVM内存模式指的是JVM的内存分区;而Java内存模式是一种虚拟机规范。

Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。

Java内存模型带来的问题

可见性问题

CPU中运行的线程从主存中拷贝共享对象obj到它的CPU缓存,把对象obj的count变量改为2。但这个变更对运行在右边CPU中的线程不可见,因为这个更改还没有flush到主存中:要解决共享对象可见性这个问题,我们可以使用java volatile关键字或者是加锁

Java内存模型-JMM

竞争现象

线程A和线程B共享一个对象obj。假设线程A从主存读取Obj.count变量到自己的CPU缓存,同时,线程B也读取了Obj.count变量到它的CPU缓存,并且这两个线程都对Obj.count做了加1操作。此时,Obj.count加1操作被执行了两次,不过都在不同的CPU缓存中。如果这两个加1操作是串行执行的,那么Obj.count变量便会在原始值上加2,最终主存中的Obj.count的值会是3。然而下图中两个加1操作是并行的,不管是线程A还是线程B先flush计算结果到主存,最终主存中的Obj.count只会增加1次变成2,尽管一共有两次加1操作。 要解决上面的问题我们可以使用java synchronized代码块。

Java内存模型-JMM

Java内存模型中的重排序
在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排序。

Java内存模型-JMM

  • 编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。
  • 指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-LevelParallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。
  • 内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。

volatile内存语义的实现——JMM对volatile的内存屏障插入策略:
在每个volatile写操作的前面插入一个StoreStore屏障。在每个volatile写操作的后面插入一个StoreLoad屏障。
在每个volatile读操作的后面插入一个LoadLoad屏障。在每个volatile读操作的后面插入一个LoadStore屏障。

 

 

- THE END -

木之本 桜

4月06日15:07

最后修改:2022年4月6日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论