单例模式-各种实现总结

饿汉式

饿汉式是最简单最直接的,在单例数量较少的应用里推荐使用这种方式。
优点: 线程安全
缺点: 类加载时就初始化,耗费不必要的资源

直接赋值

public class HungrySingleton {
    private static final HungrySingleton INSTANCE = new HungrySingleton();

    private HungrySingleton(){}

    public static HungrySingleton getHungrySingleton() {
        return INSTANCE;
    }
}

静态块赋值

public class HungryStaticSingleton {
    private static final HungryStaticSingleton INSTANCE;

    static {
        INSTANCE = new HungryStaticSingleton();
    }
    private HungryStaticSingleton(){}

    public static HungryStaticSingleton getHungrySingleton() {
        return INSTANCE;
    }
}

懒汉式

简单版

优点: 调用时才加载,对比饿汉式减少资源开销
缺点: 线程不安全,并发情况下可能创建多实例破话单例模式

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton(){}

    public static LazySingleton getLazySingleton() {
        if (instance == null) {
            return new LazySingleton();
        }
        return instance;
    }
}

double check(双重校验)

解决懒汉式线程安全问题,最简单粗暴的方法就是在获取实例方法上加锁。但是这种方式会降低性能,而双重校验单例模式即保证了线程安全又解决了性能问题。
优点:简单版基础上解决了线程问题,且性能最优
缺点: 代码逻辑复杂、可读性查,编码不优雅

public class LazyDoubleCheckSingleton {
    private static LazyDoubleCheckSingleton instance;

    private LazyDoubleCheckSingleton(){}

    public static LazyDoubleCheckSingleton getLazySingleton() {
        // 并发情况下,之前线程已经创建了对象,之后线程就会被拦截不走同步方法,提升性能
        if (instance == null) {
            synchronized (LazyDoubleCheckSingleton.class) {
                // 并发情况下,初始并发下判断不重复创建
                if (instance == null) {
                    return new LazyDoubleCheckSingleton();
                    // 这里可能会出现CPU指令重排序的问题 [参考这篇文章解决](https://www.cnblogs.com/xll1025/p/6486170.html)
                }
            }
        }
        return instance;
    }
}

内部类

优点: 对比double check方式,优雅的解决了线程、性能问题(内部类是延时加载)

public class LazyStaticInnerSingleton {

    private LazyStaticInnerSingleton(){
    }

    public static final LazyStaticInnerSingleton getInstance(){
        return LazyHolder.INSTANCE;
    }

    private static final class LazyHolder{
        public static final LazyStaticInnerSingleton INSTANCE = new LazyStaticInnerSingleton();
    }
}

懒汉式、饿汉式 都存在一个问题:通过反射机制调用私有构造方法,创建多个实例破坏单例模式。使用注册式(枚举式、容器式)可以解决这个问题,枚举底层使用一个Map容器实现的,和spring使用的容器式比较类似
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值