java 内存模型三大特性_Java内存模型的三大特性

之所以关注这个java内存模型的三大特性,源于看到java单例模式的最佳懒汉模式的写法:

// 双重校验锁DCL(double checked locking)

public class Singleton {

private static volatile Singleton sInstance;

private Singleton() {

}

public static Singleton getInstance() {

if (sInstance == null) {

synchronized (Singleton.class) {

if (sInstance == null) {

sInstance = new Singleton();

}

}

}

return sInstance;

}

}

如果没有用volatile修饰的话,这个获取到的单例实例是有问题的。因为

sInstance = new Singleton();

不是原子性的,它其实是一下三个步骤

1.为对象分配内存

2.执行构造方法语句,初始化实例对象

3.把sInstance的引用指向分配的内存空间

这三个步骤不一定是按顺序执行的,因为在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。所以可能执行的顺序是1-->3-->2

当执行完3时,这时候sInstance不为空,但是未进行初始化,这时候cpu切换执行权,另外一个线程在执行外层的

if(sInstance == null){

}

发现sInstance不为null,则直接return回来了,因为这个实例是未进行初始化的,所以是有问题的。

这是后就必须加上volatile,volatile能保证可见性和有序性,可以阻止

sInstance = new Singleton();

的重排序,按照正常1-->2-->3执行。而synchronized只能保证互斥性和原子性。这里可以参考下,大神的关于java内存模型的知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值