单例模式

饿汉式

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

    public HungrySingleton() {

    }

    public static HungrySingleton getInstance() {
        return hungrySingleton;
    }

    public void log() {
        System.out.println("I am hungry");
    }
}

饿汉式实现方式较为简单,假如加载的对象比较大,那么延迟加载不会是个好方法,所以饿汉式完全胜任。
但是假如说加载了个可有可无或者利用率非常低的方法,那么延迟加载就会出现

懒汉式

public class LazySingleton {
    private LazySingleton lazySingleton;

    private LazySingleton() {

    }

    public synchronized LazySingleton getInstance() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }

}

那么,上面的实现有什么缺陷?

加了synchronized这把锁,不过有没有对象都会串行化执行,那么它的并行度趋近于1,假如这样会大大降低执行效率。

这时,双重检测机制就出现了。

懒汉式(双重检测)

public class LazySingleton {
    private LazySingleton lazySingleton;

    private LazySingleton() {

    }
    public LazySingleton getInstance() {
        if (lazySingleton == null) {
            synchronized (LazySingleton.class) {
                if (lazySingleton == null) {
                    lazySingleton = new LazySingleton();
                }
            }
        }
        return lazySingleton;
    }
}

如上实现所示,每次进入getInstance这个方法时,检测是否存在对象,再决定是否加锁,解决了synchronized串行化影响效率的问题。

静态内部类

public class StaticInnerClassSingleton {

    static class Inner {
        public static final StaticInnerClassSingleton staticInnterClassSingleton = new StaticInnerClassSingleton();
    }

    private StaticInnerClassSingleton() {

    }

    public static StaticInnerClassSingleton getInstance() {
        return Inner.staticInnterClassSingleton;
    }
}

使用静态内部类,既可以解决串行化影响效率,又可以延迟加载。实现方式简单。

枚举单例

enum EnumSingleton {
    ENUM_SINGLETON;

    public void log() {
        System.out.println("I am ENUM_SINGLETON");;
    }
}

单例模式的缺点

单例模式很多时候被认为是一种反模式的设计模式。

对OOP的支持不好

假如说用单例模式做一个ID生成器,UserID用IDGenerator,OrderID也用IDGenerator,有一天不同业务需要不同的IDGenerator,这样就会在User类中与Order类中大动干戈。

单例模式会隐藏调用关系

举个例子,假如说注入的方式去调用,可读性会变得很好,但是单例会隐藏各个依赖之间的调用关系,会降低可读性。

单例模式对代码的拓展性不友好

假如有一个数据库连接池使用了单例,短期看并没有问题,假如说突然变得很慢,需要加一个数据库连接池去做快SQL,这个慢SQL后台处理,这样做就会相当麻烦,因为单例模式的对象一初始化就无法变更内容。

单例模式不支持有参数的构造函数

解决方案1是:
使用init对象然后对单例模式进行传参

解决方案2是:
使用getInstance函数进行传参

当使用解决方案2解决的时候,发现一次初始化,再次传入参数时就无法变更里面的参数,
这样子的话可以在初始化构造方法的时候进行参数校验,看oldVal和newVal是否相等,
若不等就传新的进去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值