Java并发编程艺术(二) Java内存模型

2022-09-11  本文已影响0人  kaiker

1、Java内存模型基础

1.1 并发编程模型的两个关键问题

线程之间如何通信、线程之间如何同步。

1.2 Java内存模型的抽象结构

Java内存模型抽象结构

1.3 源代码到指令序列的重排序

排序

1.4 并发编程模型分类

1
2 处理器重排规则 四种内存屏障

1.5 happens-before

hapens-before与JMM

2、重排序

2.1 数据依赖性

2.2 as-if-serial语义

2.3 重排序对多线程的影响

class ReorderExample {
    int     a    = 0;
    boolean flag = false;

    public void writer() {
        a = 1; //1
        flag = true; //2
    }

    public void reader() {
        if (flag) { //3
            int i = a * a; //4
            //s¡­¡­
        }
    }
}
程序执行 synchronized程序执行

3、volatile内存语义

3.1 volatile特性

3.2 volatile写-读建立的happens-before关系

class VolatileExample {
    int              a    = 0;
    volatile boolean flag = false;

    public void writer() {
        a = 1; //1
        flag = true; //2
    }

    public void reader() {
        if (flag) { //3
            int i = a; //4
            //¡­¡­
        }
    }
}
volatile happens-befor

3.3 写-读内存语义

3.4 volatile内存语义的实现

volatile重排序规则表

基于保守策略的JMM内存屏障:

volatile写
volatile读

4、锁的内存语义

4.1 锁的释放获取建立的happens-before关系

class MonitorExample {
    int a = 0;

    public synchronized void writer() { //1
        a++; //2
    } //3

    public synchronized void reader() { //4
        int i = a; //5
        //¡­¡­
    } //6
}
锁 happens-before

4.2 锁的释放和获取的内存语义

4.3 锁内存语义的实现

class ReentrantLockExample {
    int           a    = 0;
    ReentrantLock lock = new ReentrantLock();

    public void writer() {
        lock.lock(); 
        try {
            a++;
        } finally {
            lock.unlock(); 
        }
    }

    public void reader() {
        lock.lock(); 
        try {
            int i = a;
            //¡­¡­
        } finally {
            lock.unlock();
        }
    }
}
ReentrantLock类图 tryAcquire

5、final域的内存语义

5.1 final域的重排序规则

public class FinalExample {
    int                 i; 
    final int           j;  
    static FinalExample obj;

    public FinalExample() {
        i = 1; 
        j = 2; 
    }

    public static void writer() { 
        obj = new FinalExample();
    }

    public static void reader() { 
        FinalExample object = obj; 
        int a = object.i; 
        int b = object.j; 
    }
}

5.2 写final域的重排序规则

final写

5.3 读final域的重排序规则

final读

6、happens-before

规则

join规则

7、双重检查锁定与延迟初始化

public class DoubleCheckedLocking { //1
    private static Instance instance; //2

    public static Instance getInstance() { //3
        if (instance == null) { //4
            synchronized (DoubleCheckedLocking.class) { //5
                if (instance == null) //6
                    instance = new Instance(); //7
            } //8
        } //9
        return instance; //10
    } //11

    static class Instance {
    }
}
memory = allocate();  // 分配空间
ctorInstance(memory); // 初始化对象
instance = memory; // 设置instance指向刚分配的内存地址
执行顺序

7.1 基于volatile解决

public class SafeDoubleCheckedLocking {
    private volatile static Instance instance;

    public static Instance getInstance() {
        if (instance == null) {
            synchronized (SafeDoubleCheckedLocking.class) {
                if (instance == null)
                    instance = new Instance();
            }
        }
        return instance;
    }

    static class Instance {
    }
}

7.2 基于类初识化

public class InstanceFactory {
    private static class InstanceHolder {
        public static Instance instance = new Instance();
    }

    public static Instance getInstance() {
        return InstanceHolder.instance; 
    }

    static class Instance {
    }
}
类初始化

类初始化过程,竞争的类会读取到state,拿到初始化锁的那个类会修改这个值。

第1阶段
第2阶段
第4阶段
上一篇 下一篇

猜你喜欢

热点阅读