Singleton Pattern 单例模式

01 Singleton Pattern 单例模式

  • 概念:单例的对象只能有一个实例存在
  • 实现方式:一个类能返回对象的一个引用(永远是同一个)和一个获得该唯一实例的方法(必须是静态方法)
  • 目的:保证系统中只有一个实例,从而在某些特定的场合下达到节约或者控制系统资源的目的
  • 适用:当你只需要一个实例对象的时候,就可以考虑适用单例模式
    如在资源共享的情况下,避免由于多个资源操作导致的性能或耗损等

02 懒汉式的单例模式

优:单例对象的生成是在应用需要使用单例对象时才去构造,可以提高应用启动速度
缺:不是线程安全,如果多个线程同时调用getInstance方法,那么可能会生成多个单例对象
适用:单例对象功能复杂,占用内存大,对应用的启动速度有要求
不适用:多线程同时使用

public class LazySingleton {
    private static LazySingleton lazySingleton = null;
    
    // 私有构造器,不让外部通过new创建对象
    
    private LazySingleton() {}

    public static LazySingleton getInstance() {
        if(null == lazySingleton) {
            // 当为空时,在类内部通过new关键字创建
            lazySingleton = new LazySingleton();
        }
        return singleton;
    }
}

03 饿汉式的单例模式

优:简单方便 安全可靠
缺:不管程序中是否使用到单例对象,都会生成单例对象,并由静态对象是在类加载时就需要生成,会降低应用启动速度
适用:类对象功能简单,占用内存较小,使用频繁
不适用:类对象功能复杂,占用内存大,使用概率较低

public class HungrySingleton {
    // 类被加载时就创建实例
    private static final hungrySingleton = new HungrySingleton();
    
    private HungrySingleton() {}
    
    public static HungrySingleton getInstance() {
        return hungrySingletion;
    }
}

04 加锁的懒汉式 线程安全

优:同懒汉式
缺:加锁后有额外消耗

public class LockSingleton {
    private static LockSingleton lockSingleton = null;
    
    private LockSingleton() {}
    
    /* 懒汉同步锁
    获取方式 添加锁对象
    添加线程保护机制,确保线程安全 */
    public static LockSingleton getInstance() {   
        // 线程同步
        synchronized (LockSingleton.class) {
            if(null = LockSingleton) {
                lockSingleton = new LockSingleton();
            }
        }
        return lockSingleton;
    }
}

05 双重校验加锁的懒汉式#1

优:懒加载 线程安全 效率高
缺:代码较复杂

public class DoubleCheckLockSingleton {
    private static DoubleCheckLockSingleton doubleCheckLockSingleton = null;
    
    private DoubleCheckLockSingleton() {}
    
    // 双重校验 + 锁模式
    public static DoubleCheckLockSingleton() {
        if(null == doubleCheckLockSingleton) {
            synchronized (DoubleCheckLockSingleton.class) {
                if(null == doubleCheckLockSingleton) {
                    doubleCheckLockSingleton = new DoubleCheckLockSingleton();
                }
            }
        }
        /* 单例模式不为空,直接返回单例
        不需要判断线程同步锁和构造单例对象
        减少判断线程同步锁的次数,从而提高效率 */
        return doubleCheckLockSingleton();
    }
}

05 双重校验加锁的懒汉式#2

public class DoubleCheckLockSingleton {
    /* volatile 防止编译器自行优化代码 JVM
    老版本JDK中无法正常工作 */
    private volatile static DoubleCheckLockSingleton doubleCheckLockSingleton = null;
    
    private DoubleCheckLockSingleton() {}
    
    // 双重校验 + 锁模式
    public static DoubleCheckLockSingleton() {
        if(null == doubleCheckLockSingleton) {
            synchronized (DoubleCheckLockSingleton.class) {
                if(null == doubleCheckLockSingleton) {
                    doubleCheckLockSingleton = new DoubleCheckLockSingleton();
                }
            }
        }
        /* 单例模式不为空,直接返回单例
        不需要判断线程同步锁和构造单例对象
        减少判断线程同步锁的次数,从而提高效率 */
        return doubleCheckLockSingleton();
    }
}

06 内部静态类实现的懒汉式

优:实现简单,懒加载,线程安全
缺:增加了一个静态内部类,apk文件增大 why

public class InnerClassSingleton {
    /* 内部静态类
    Java静态内部类是使用到该静态的时候才去加载的 线程安全 */
    private static class InnerClassSingletonInstance {
        private static final InnerClassSingleton innerClassSingleton = new InnerClassSingleton();
    }
    
    private InnerClassSingleto() {} 
    
    /* 内部类静态获取
    InnerClassSingletonInstance是私有的,除了getInstance()之外没有其他方式可以访问实例对象
    当调用getInstance()方法时才会去真正的创建实例对象 */
    public static InnerClassSingletonInstance getInstance() {
        return InnerClassSingletonInstance.innerClassSingleton;
    }
}

07 使用枚举的单例模式

优:线程安全,不用担心序列化和反射问题 防止反序列化带来的问题 why
缺:枚举占用内存多一点 why

public enum EnumSingleton { 
    // 通过EnumSingleton.INSTANCE来访问实例对象
    INSTANCE;
    
    private String field;
    
    public String getField() {
        return field;
    }
    
    public void setField(String field) {
        this.field = field;
    }
}

参考资料

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值