[水]单例设计模式的常见写法与多线程时多单例怎么避免

众所周知,单例模式的“懒汉”写法在多线程时运行可能会出现多实例,即,在多线程时,可能多个线程同时判断实例为null,然后对实例进行创建,使用双重锁对创建操作加锁可以避免多次创建。使用volatile关键字修饰对象,保证创建后主内存立即同步,避免多线程时,线程已经创建对象,但其他线程不可见,返回为null。
可以使用以下写法避免。

一:单例模式的坑怎么避免

1、使用synchronized关键字做双重检查锁

对需要判定只执行一次的操作加双重校验锁,即一次判断是否操作,一次对操作加锁。

注意:对象需要使用


/**
 * 双重检查锁,解决多线程可能出现的多实例问题
 */
public class SingleTon2 {

    private static volatile SingleTon2 singleton;

    private SingleTon2() {
    }

    public static SingleTon2 getInstance() {
        if (singleton == null) {
            synchronized (SingleTon2.class) {
                if (singleton == null) {
                    singleton = new SingleTon2();
                }
            }
        }
        return singleton;
    }

    //类中其他方法,尽量是static
    public static void doSomething() {
        System.out.println("this is a singleInstance");
    }
}

2、使用枚举类获取单例

单例类如下:


/**
 * 用于演示枚举类单例
 */
public class SingleTon3 {

    //类中其他方法,尽量是static
    public static void doSomething() {
        System.out.println("this is a singleInstance");
    }
}

单例类对应枚举如下:



/**
 * 单元素枚举类单例
 * 原理:枚举中枚举是 static final 的
 * 访问枚举实例时会执行构造方法,在调用构造方法时,我们的单例被实例化。
 * enum中的实例被保证只会被实例化一次,所以我们的INSTANCE也被保证实例化一次。
 * <p>
 * 使用,使用 SingleTonEnum.INSTANCE.getInstance()获取单例
 *
 */
public enum SingleTonEnum {

    INSTANCE;

    private SingleTon3 singleTon;

    SingleTonEnum() {
        singleTon = new SingleTon3();
    }

    public SingleTon3 getInstance() {
        return singleTon;
    }
}

说的好,我选择饿汉模式,哈哈哈哈哈

关于单例,还有一个是可能的序列化如何破坏单例模式,个人觉得没必要在意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值