happens-before是一些规则,规定了某个线程修改的变量何时对其他线程可见。从JDK 5 开始,JMM就使用happens-before的概念来阐述多线程之间的内存可见性。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系。
happens-before原则定义如下:
happens-before规则:
说了这么多happends before原则,那么它是如何实现的呢?
比如volatile规则是volatile产生内存屏障保证了读在写之后进行的。程序次序规则、锁定规则是处理器和编辑器规则来决定的。
happen-before原则是JMM中非常重要的原则,它是判断数据是否存在竞争、线程是否安全的主要依据,保证了多线程环境下的可见性。
下图是happens-before与JMM的关系图(摘自《Java并发编程的艺术》)
前面提到了volatile,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能立即读到这个修改的值。如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。
注意:volatile保证了内存可见性,但是不保证原子性。volatile修饰的共享变量进行写操作时会多出Lock前缀的指令(CPU指令),Lock前缀的指令会引发下面两件事情:
● 将当前处理器缓存行的数据写回到系统内存。
● 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。
推荐阅读