1. 前言
可见性、有序性和原子性导致了并发编程的各种问题。
导致可见性的原因是缓存,导致有序性的原因是编译优化。解决这两个问题的直接方法就是按需禁用缓存和编译优化。
java内存模型规范了JVM如何提供按需禁用内存和编译优化的方法。这些技术主要包含volatile关键字、Happens-Before规则和final关键字。
2. volatile
volatile关键字用于修饰一个变量,作用就是禁用缓存。
当一个变量被volatile修饰,就是要告诉编译器,只能从内存中读取该变量,也只能写入到内存中。
3. Happens-Before规则
事件A happens before事件B,意思就是事件A对事件B来说是可见的,或者说事件B能看见事件A作出的变化。
3.1 顺序性规则
这个规则简单来说就是,在一个单独的线程中,前一行代码happens before后一行代码。虽然还会存在指令重排序,但是不管怎么排,得到的结果符合我们的代码顺序。该规则在多线程中不能保证。
比如,下面的类中,
class HappensBeforeTest{
int x;
volatile boolean y = false;
public void write(){
x = 1;
y