加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

【设计模式(三)】单例模式——单例有几种写法?

发布时间:2020-12-15 05:34:05 所属栏目:Java 来源:网络整理
导读:有一回对我说道,“你写过编程么?”我略略点一点头.他说,“写过,……我便考你一考.单例模式,是怎样写的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会.孔乙己等了许久,很恳切的说道,“ 不能写罢?……我教给你,记着! 单例模式(Singleton Pattern) 单

有一回对我说道,“你写过编程么?”我略略点一点头.他说,“写过,……我便考你一考.单例模式,是怎样写的?”我想,讨饭一样的人,也配考我么?便回过脸去,不再理会.孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!

单例模式(Singleton Pattern)

单例模式是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

单例模式三要素:1.单例类只能有一个实例。 2.单例类必须自己创建自己的唯一实例。 3.单例类必须给所有其他对象提供这一实例。

应用场景

1.游戏开发中的跟随主角视角的摄像头,一般只有一个

2.要求生产唯一序列号,用来防伪

3.WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来

4.创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等

?

单例模式的四种写法

虽然演示语言是typescript,最终以javascript实现,而js没有多线程,不用考虑线程安全问题。但笔者依然会列出其中的线程安全问题,ts不考虑,java、c还是要的。

懒汉模式

class SingleTest {
    private static instance: SingleTest;
    constructor() {

    }

    public static getInstance(): SingleTest {
        if(this.instance == null) 
            this.instance = new SingleTest();
        return this.instance;
    }
}

这是最基本的实现方式,为什么叫懒汉?因为要等别人调用了你才实例化对象,有够懒的。缺点很明显:不支持多线程。如果要保证线程安全,需要加锁synchronized,当然也会影响效率。

饿汉模式

class Singleton {  
    private static instance:Singleton  = new Singleton();  
    constructor (){}  
    public static getInstance(): Singleton {  
    return this.instance;  
    }  
}

很常用的模式。为什么叫饿汉?因为类在装载的时候你就实例化了,别人还没上桌你就吃完了,饿死鬼投胎!容易写,而且执行效率会提高。缺点也很明显:类加载时就初始化,浪费内存,容易产生垃圾对象。

以下模式为多线程语言的设计模式,所以不用ts演示了。

双检锁/双重校验锁(DCL,即 double-checked locking)

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
}

这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

登记式/静态内部类

public class Singleton {  
    private static class SingletonHolder {  
    private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}

这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。

枚举

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。但是需要JDK1.5 之后加入的enum 特性才可使用。

?

孔乙己显出极高兴的样子,将两个指头的长指甲敲着柜台,点头说,“对呀对呀!……单例模式有四样写法,你知道么?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读