Java 并发内存模型

2019-02-20  本文已影响0人  qingshuiting

Java 并发内存模型

并发中的问题

synchronized关键字

进入synchronized:在进入synchronize以后,共享变量的缓存会失效,所以使用的时候需要从主内存中获取。

退出synchronized:在退出synchronize的时候,会将缓冲区(进入synchronize前或者在synchronize中修改的变量)的数据写入到主内存中。所以共享变量的修改对其他线程可见是在synchronize退出以后。

单例分析

public class Singleton {

    private static Singleton instance = null;

    private int v;
    private Singleton() {
        this.v = 3;
    }

    public static Singleton getInstance() {
        if (instance == null) { // 1. 第一次检查
            synchronized (Singleton.class) { // 2
                if (instance == null) { // 3. 第二次检查
                    instance = new Singleton(); // 4
                }
            }
        }
        return instance;
    }
}

模拟两个线程:线程A和线程B。线程A执行到instance = new Singleton()代码。这段代码的指令可以分解为两个部分:申请内存,并且使用构造方法初始化属性;然后把对象的引用赋值给instance。这两条只能可能会发生重新排序的。

如果线程B 这个时候执行到了if (instance == null) 那么有可能看到的instance不是null,因为有可能线程A在获得对象的引用之后,就马上把instance写回了主内存,然后线程B在第一行代码又从主内存中读取了新的instance值,发现instance不是null就马上返回了,但是这个时候线程B拿到的instance对象里面的属性可能是未初始化好的。

但是如果线程A 走出了synchronized代码块,那么instance一定是完整的内容。

volatile的使用

所以volatile的作用就非常明显了,如果我们需要多线程之间的变量具有立即可见性,就需要对变量使用volatile。

并且:由于long,double是64位的,但是java写入是32位32位的写入,所以鼓励使用volatile来进行

上一篇下一篇

猜你喜欢

热点阅读