单例模式

饿汉式是没有线程安全问题的,下面主要说下懒汉式的安全模式

一、double check

package Singleton;

/**
 * 类描述:test
 */
public class Singleton {
    private Singleton() {}
    
    private volatile static Singleton instance = null;
    
    public static Singleton getInstance() {
        if(instance == null) {
            synchronized (Singleton.class) {
                if(instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

一般的double check是会有线程安全问题的,这是因为对象的创建有3个步骤:

1、给对象分配内存空间

2、初始化对象

3、将引用instance指向分配的内存空间

由于jvm和cpu可能进行优化而进行重排序,这样的话第2和3步交换顺序,在执行到第3步时恰巧判断了instance是否为null,这个时候就会返回一个没有初始化完成的install对象,这是有问题的

所以在这里的instace加上了关键字volatile修饰,根据jmm的规则保证了初始化对象的顺序,所以线程安全问题解决

二、枚举方式(推荐)

package Singleton;

/**
 * 类描述:test
 */
public class SingletonEnum {
    private SingletonEnum() {}

    public static SingletonEnum getInstance() {
        return Singleton.INSTANCE.getInstance();
    }
    
    private enum Singleton {
        INSTANCE;
        
        private SingletonEnum instance;
        
        Singleton() {
            instance = new SingletonEnum();
        }
        
        public SingletonEnum getInstance() {
            return instance;
        }
    }
}

这个是通过利用枚举的特性,JVM会保证枚举的构造函数只会调用一次,所以肯定是线程安全的,另外这里起到了资源的合理利用,只有在真正用到实例的时候采取初始化对象了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值