Java内存屏障(Memory Barriers)

/ Java / 没有评论 / 1432浏览

Java内存屏障(Memory Barriers)

我百度翻译了一下“Memory Barriers”,给出的结果是:记忆障碍。让我大吃一惊。实际上,我们在程序中叫它内存屏障。本文将介绍一下java中的内存屏障(Memory Barriers)。

内存屏障(Memory Barrier,或有时叫做内存栅栏,Memory Fence)是一种CPU指令,用于控制特定条件下的重排序和内存可见性问题。Java编译器也会根据内存屏障的规则禁止重排序。

java内存屏障

java 的内存屏障通常所谓的四种即LoadLoad、StoreStore、LoadStore、StoreLoad 。

有的处理器的重排序规则较严,无需内存屏障也能很好的工作,Java编译器会在这种情况下不放置内存屏障。

volatile语义中的内存屏障

volatile的内存屏障策略非常严格保守,非常悲观且毫无安全感的心态:

由于内存屏障的作用,避免了volatile变量和其它指令重排序、线程之间实现了通信,使得volatile表现出了锁的特性。

final语义中的内存屏障

对于final域,编译器和CPU会遵循两个排序规则:

  1. 新建对象过程中,构造体中对final域的初始化写入和这个对象赋值给其他引用变量,这两个操作不能重排序;(废话嘛)
  2. 初次读包含final域的对象引用和读取这个final域,这两个操作不能重排序;(晦涩,意思就是先赋值引用,再调用final值)

也就是说必需保证一个对象的所有final域被写入完毕后才能引用和读取。这也是内存屏障的起的作用。

写final域:在编译器写final域完毕,构造体结束之前,会插入一个StoreStore屏障,保证前面的对final写入对其他线程/CPU可见,并阻止重排序。

读final域:在上述规则2中,两步操作不能重排序的机理就是在读final域前插入了LoadLoad屏障。

参考资料