来动手写一个安全的单例

本贴最后更新于 2603 天前,其中的信息可能已经时移俗易

序言

犹记得当初老师跟我们讲设计模式时候问我们对象的创建有两种模式,一种是饿汉模式,还有一种呢?我们认为是饱汉模式。。。

饿汉模式

也就是立即加载,当使用类的时候对象已经创建完毕

public class StarveObject {
    private static StarveObject starveObject = new StarveObject();

    public StarveObject() {
    }
    public static StarveObject getInstance(){
        return starveObject;
    }
}

懒汉模式

延迟加载,当调用 get 方法时候对象才被创建

public class LazyObject {
    private static LazyObject lazyObject;

    public LazyObject() {

    }
    public static LazyObject getInstance(){
        if (lazyObject != null) {

        } else {
            lazyObject = new LazyObject();
        } 
        return lazyObject;
    }
}

但是上面的单例设计存在问题,当在多线程环境下,就很可能创建出多个实例。于是我想到了加 synchronized 关键字

synchronized public static LazyObject getInstance(){
    if (lazyObject != null) {

    } else {
        lazyObject = new LazyObject();
    }
    return lazyObject;
}  

这样做就解决了问题,但是每个线程想要获取该单例对象的时候都需要等待锁,浪费了很多时间。

DCL 双检查锁创建单例

public static LazyObject getInstance(){
    if (lazyObject != null) {

    } else {
        synchronized (LazyObject.class) {
            if (lazyObject == null) {
                lazyObject = new LazyObject();
            }
        }
    }
    return lazyObject;
}    

使用静态内置类实现单例


public static LazyObject getInstance(){ 

    if (lazyObject != null) {

    } else {
        synchronized (LazyObject.class) {
            if (lazyObject == null) {
                lazyObject = new LazyObject();
            }
        }
    }
    return lazyObject;
}  

利用 enum 枚举实现单例

public class MyEnum {
    private Connection connection;

    public MyEnum(MyEnum myEnum) {
        connection = new Connection();
    }
    public Connection getConnection(){
        return connection;
    }
}  

  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖
  • 单例
    6 引用

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...