4种单例模式实现

多线程下的单例模式

1、懒汉模式

// 饿汉模式(线程安全)
public class Singleton {
    // 私有化构造器,不允许创建对象
    private Singleton(){}
    // 加载的时候就产生的实例对象ClassLoader
    private static Singleton instance = new Singleton();
    // 返回实例
    public Singleton getInstance(){
        return instance;
    }
}

2、饿汉模式

// 懒汉模式
public class SingletonDemo {
    // volatile的作用是可以使内存中的数据对象线程可见
    // 主内存对线程是不可见的,添加volatile关键字之后,主内存对线程可见
    // 使用volatile后直接跳过工作内存复制一份的情况,进行主内存操作判断是否为空
    // 如果不加volatile,可能会引起指令重排,导致空指针异常
    private volatile static  SingletonDemo singleton;
    private SingletonDemo(){
        System.out.println("创建了单例对象!");
    }
    // double check
    public static SingletonDemo getInstance(){
        //必须是一个唯一的对象
        if(singleton == null){
            synchronized (SingletonDemo.class){
                if(singleton == null){
                    singleton = new SingletonDemo();
                }
            }
        }
        return singleton;
    }
}

【分析】:不加volatile关键字的影响

修改代码:

private Socket socket;
private static SingletonDemo singleton;
private SingletonDemo(){
    socket = new Socket();
    singleton = new SingletonDemo();
    socket.toString();
}

在初始化的时候,根据JVM优化,可能在编译期代码重排,运行期指令重排,导致socket.toString()在没有被初始化的情况下优先执行,就会导致空指针异常,所以必须加volatile关键字,这样singleton = new SingletonDemo();前面的代码就不会被改变执行顺序不会出现空指针了。

内部类下的单例模式

声明类的时候,成员变量中不声明实例变量,而放到内部静态类中。

public class OutHolder {
    private OutHolder(){}
    private static class InnerHolder{
        private static OutHolder holder = new OutHolder();
    }
    // 懒加载,调用的时候才会初始化(内部类会延迟加载)
    public static OutHolder getInstance(){
        return InnerHolder.holder;
    }
}

枚举类下的单例模式

public enum EnumDemo{
    // INSTANCE是一个常量,在加载的时候只实例化一次,类型为EnumDemo
    // 相当于EnumDemo INSTANCE = new EnumDemo();
    INSTANCE;
    public static EnumDemo getInstance(){
        return INSTANCE;
    }
}

单例模式:

public class EnumSingleton {
    private EnumSingleton(){}
    // 延迟加载
    private enum EnumHolder{
        // EnumHolder类型的常量
        INSTANCE;
        private EnumSingleton instance;
        EnumHolder(){
            this.instance = new EnumSingleton();
        }
        public EnumSingleton getInstance(){
            return instance;
        }
    }
    public static EnumSingleton getInstance(){
        return EnumHolder.INSTANCE.instance;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Please Sit Down

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值