设计模式 单例模式

单例模式

一 概念

  • 分类

创建型模式✔

结构型模式

行为型模式

  • 含义

单例类只能有一个实例

单例类必须自己创建自己的唯一实例

单例类必须给所有其他对象提供这一实例

  • 意图

       保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 主要解决

         一个全局使用的类频繁地创建与销毁。

  • 何时使用

         当您想控制实例数目,节省系统资源的时候。

  • 如何解决

          判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

  • 关键代码

          构造函数是私有的。

  • 创建

一个静态实例

一个 静态实例获取方法

构造函数私有

注意:getInstance() -- synchronized (Singleton.class)     --多线程造成多次实例化

 二 实现方式

  懒汉模式1:不支持多线程

public class Singleton { 

    private static Singleton instance; 

    private Singleton (){} 

    public static Singleton getInstance() { 

    if (instance == null) { 

        instance = new Singleton(); 

    } 

    return instance; 

    } 

}

 

懒汉模式2:在jvm进程启动并在我们主动使用该类的时候不会在内存中初始化一个单例对象,只有当我们调用getInstance()的时候才去创建该对象,他的创建是在我们调用getInstance()静态方法之后,为了并没现象同步问题,我们在getInstance()方法上加了一个锁。

优点:第一次调用才初始化,避免内存浪费。具备很好的 lazy loading

缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率

public class Singleton { 

    private static Singleton instance; 

    private Singleton (){} 

    public static synchronized Singleton getInstance() { 

    if (instance == null) { 

        instance = new Singleton(); 

    } 

    return instance; 

    } 

}

 

饿汉模式:饿汉模式就是在jvm进程启动并在我们主动使用该类的时候就会在内存中初始化一个单例对象,当我们调用getInstance()的时候直接获取该对象,他的创建是在我们调用getInstance()静态方法之前

优点:没有加锁,执行效率会提高

缺点:类加载时就初始化,浪费内存

classloader 机制

public class Singleton { 

    private static Singleton instance = new Singleton(); 

    private Singleton (){} 

    public static Singleton getInstance() { 

    return instance; 

    } 

}

 

双重校验锁:双锁机制  安全  多线程情况下能保持高性能   实例域延迟初始化

volatile的作用:解决了由于重排序的原因,在线程执行到第一次检查时,代码读取到instance不为null时,instance引用的对象有可能还没有完成初始化

参考:单例模式中volatile关键字的作用

    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() { 

    } 

}

posted @ 2021-01-24 18:45  aczy  阅读(84)  评论(0编辑  收藏  举报