本文共 1178 字,大约阅读时间需要 3 分钟。
上一篇介绍了java的内存结构,那么接下来总结java在多核多线程的环境下如何解决数据访问的复杂问题。
二、JMM与线程规范
我们知道,计算机按支持的指令大致可以分为两类:
力相对较弱。
强,以及AMD的CPU。
java在这样的背景下,与2014年最终修订了JSR-133规范。JMM规范明确定义了不同的线程之间,通过哪些方式,在什么时候可以看见其他线程保存到共享变量中的值;以及在必要时,如何对共享变量的访问进行同步。这样的好处是屏蔽各种硬件平台和操作系统之间的内存访问差异,实现了Java并发程序真正的跨平台。
前面提到了CPU会在合适的时机,按需要对将要进行的操作重新排序,但是有时候这个重排机会导致我们的代码跟预期不一致。怎么办呢?JMM引入了内存屏障机制。
内存屏障可分为读屏障和写屏障 ,用于控制可见性。 常见的内存屏障包括:
#LoadLoad#StoreStore#LoadStore#StoreLoad
这些屏障的主要目的,是用来短暂屏蔽CPU的指令重排序功能。和CPU约定好,看见这些指令时,就要保证这个指令前后的相应操作不会被打乱。
#StoreLoad 屏障, 能确保屏障之前执行的所有store操作,都对其他处理器可见; 在屏障后面执行的load指令, 都能取得到最新的值。换句话说, 有效阻止屏障之前的store指令,与屏障之后的load指令乱序 、即使是多核心处理器,在执行这些操作时的顺序也是一致的。
如何理解呢? 就是只要有一个CPU内核收到这类指令,就会做一些操作,同时发出一条广播, 给某个内存地址打个标记,其他CPU内核与自己的缓存交互时,就知道这个缓存不是最新的,需要从主内存重新进行加载处理。
转载地址:http://qovkf.baihongyu.com/