单例模式的作用及创建方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式的作用及创建方法相关的知识,希望对你有一定的参考价值。

参考技术A

单例模式作为常见的设计模式之一,在java的项目开发中会时常的用到。Java Singleton模式即保证在JVM运行时,一个类Class只有一个实例存在。

单例模式有什么好处呢?
最简单的一个例子就是网站计数器的设计了。当我们想要统计当前网站的在线人数时,一个显而易见的问题就是并发所带来的线程安全问题,当我们对这个计数器(网站人数)在同一时刻进行操作,再保存计数时就会造成数据的混乱,后者覆盖前者的结果。一种解决方案就是把这个计数器设置为唯一对象,所有人都必须共用同一份数据。
实现唯一对象最好的解决办法就是让类自己负责保存它的唯一实例,并且让这个类保证不会产生第二个实例,同时提供一个让外部对象访问该实例的方法。自己的事情自己办,而不是由别人代办,这非常符合面向对象的封装原则。

单例模式的三个特点:

只有在自身需要的时候才会行动,从来不知道及早做好准备。它在需要对象的时候,才判断是否已有对象,如果没有就立即创建一个对象,然后返回,如果已有对象就不再创建,立即返回。

该方法在多线程情况下有可能重复创建实例,以下是线程安全的懒汉模式

这种模式的缺点是加锁造成了效率下降,并且在绝大部分情况下是不需要同步的。使用双重检验锁(DCL),只在第一次初始化的时候进行同步加锁

该方式在类加载的时候就被实例化了。

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟饿汉不同的是(很细微的差别):饿汉方式是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazy loading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显式通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。

想象一下,如果实例化instance很消耗资源,我想让它延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式就显得很合理。

关于类加载情况下单例模式,如果单例由不同的类装载器装入,那便有可能存在多个单例类的实例。假定不是远端存取,例如一些servlet容器对每个servlet使用完全不同的类 装载器,这样的话如果有两个servlet访问一个单例类,它们就都会有各自的实例。修复的办法是

Python——单例设计模式

单例设计模式:

让类创建的对象,在系统中只有唯一的实例,

使用python类内置的__new__()方法实现,__new__()方法在创建对象时会被自动调用,通过重写__new__()方法,使得无论用类型创建多少个对象,内存中都只创建一个对象的实例,此时__new__()方法必须返回此内置函数的调用,及return super().__new__(cls)

 

class MyClass():
    # 类属性,记录第一个被创建对象的引用
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self):
        print("初始化方法!")


a = MyClass()
print(a)
b = MyClass()
print(b)

 

若想使得初始化动作只执行一次:

class MyClass():
    # 类属性,记录第一个被创建对象的引用
    instance = None
    # 记录是否执行过初始化动作
    init_flag = False
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self):
        if MyClass.init_flag:
            return
        print("初始化方法!")
        MyClass.init_flag = True

a = MyClass()
print(a)
b = MyClass()
print(b)

 

以上是关于单例模式的作用及创建方法的主要内容,如果未能解决你的问题,请参考以下文章

单例模式

单例模式

单例模式及getInstance()的用法

设计模式—— 单例模式

设计模式----设计遵循法则及(简单工厂,工厂方法,单例模式)(2018/10/29)

面试篇手写单例模式及原理剖析