设计模式学习—单例模式

1、什么是单例模式?

​ 有时候,对于某些类来说,只有一个实例是很重要的。有许多对象,我们只需要它们的一个实例,如果我们实例化多个对象,就会遇到各种各样的问题,比如不正确的程序行为、资源的过度使用或结果不一致。您可能只需要一个类的一个对象。例如,当您创建应用程序的上下文、线程可管理池、注册表设置、连接到输入或输出控制台的驱动程序等。这种类型的多个对象显然会导致程序的不一致性。单例模式确保类只有一个实例,并提供对它的全局访问点。然而,尽管单例在类图方面是最简单的,因为只有一个类,但是它的实现有点棘手。

2、代码实现

1、饿汉模式:

public class SingletonEager {
    private static SingletonEager sc = new SingletonEager();
    private SingletonEager(){}
    public static SingletonEager getInstance(){
        return sc;
    }
}

这是我们的单例类,它确保只创建类的一个对象,即使有多个请求,也只返回相同的实例化对象。这种方法的一个问题是,一旦类加载到JVM中,就会创建对象。如果从来没有请求过对象,那么内存中就会有一个无用的对象。在需要对象时创建对象总是一个好方法。因此,我们将在第一次调用时创建一个对象,然后在其他连续调用时返回相同的对象。

public class SingletonLazy {
    private static SingletonLazy sc = null;
    private SingletonLazy(){}
    public static SingletonLazy getInstance(){
        if(sc==null){
            sc = new SingletonLazy();
        }
        return sc;
    }
}

此方法在多线程情况下会失败,为了保证线程安全我们必须要加synchronized

public class SingletonLazyMultithreaded {
    private static SingletonLazyMultithreaded sc = null;
    private SingletonLazyMultithreaded(){}
    public static synchronized SingletonLazyMultithreaded getInstance(){
        if(sc==null){
            sc = new SingletonLazyMultithreaded();
        }
        return sc;
    }
}

但是如果您想使用同步,还有另一种称为“双重检查锁定”的技术来减少同步的使用。使用双重检查锁定,我们首先检查是否创建了实例,如果没有,则进行同步。这样,我们只同步第一次。

public class SingletonLazyDoubleCheck {
    private volatile static SingletonLazyDoubleCheck sc = null;
    private SingletonLazyDoubleCheck(){}
    public static SingletonLazyDoubleCheck getInstance(){
        if(sc==null){
            synchronized(SingletonLazyDoubleCheck.class){
                if(sc==null){
                    sc = new SingletonLazyDoubleCheck();
                }
            }
        }
        return sc;
    }
}

3、何时使用单例?

1、一个类必须只有一个实例,并且它必须能够被客户端从一个已知的接入点访问。

2、当唯一的实例应该通过子类化来扩展,并且客户端应该能够使用扩展的实例而不需要修改他们的代码时。

你可能感兴趣的:(设计模式学习—单例模式)