单例模式

Posted xiao-lei

tags:

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

单例模式的概念

单例模式是指确保一个类只有一个唯一实例,并且提供一个全局的访问点。

单例模式的设计思路

  • 为了防止其他类利用构造方法创建多个对象,将构造方法声明为private
    类型。
  • 对外提供一个静态方法getInstance()来获取实例对象。同时应该保证无论getInstance()方法被调用多少次,得到的始终是一个对象。

单例模式的实现方式

  1. 饿汉模式
    优点:实现简单,线程安全,不用加锁,执行效率会提高。
    缺点:类加载时就初始化,浪费内存。
public class Singleton {

    // 静态成员变量
    private static Singleton instance = new Singleton();

    // 当类的构造函数为私有时,只能在本类实例化该类的对象。
    private Singleton(){
    }
   
   // 提供一个公共的静态方法返回单一实例
    public static Singleton getInstance(){
        return instance;
    }
    
}
  1. 懒汉模式
    优点: lazy loading延时加载,第一次调用才初始化,避免内存浪费。
    缺点:线程不安全,在多线程环境下不能正常工作。严格意义上不能算一种单例模式实现
public class Singleton {  

    private static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}
  1. 懒汉模式 (线程安全)
    优点: 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;  
    }  
}
  1. 懒汉模式 (双检锁/双重校验锁(DCL,即 double-checked locking))
    优点: lazy loading延时加载,第一次调用才初始化,避免内存浪费。安全且在多线程情况下能保持高性能
public class Singleton {  

    private volatile static Singleton instance;  
    private Singleton (){}  
  
    public static Singleton getInstance() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
                if (singleton == null) {  
                    singleton = new Singleton();  
                }  
            }  
        }   
        return instance;  
    }  
}
  1. 静态内部类
    优点: lazy loading延时加载,第一次调用才初始化,避免内存浪费。线程安全。
public class Singleton {  

    private Singleton (){}  
    
    // 静态内部类
    private static class SingletonHolder (){
        public static final Singleton INSTANCE = new Singleton();
    }
    // Singleton 类被装载了,instance 不一定被初始化。因为 SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance。
    public static Singleton getInstance() {  
        return SingletonHolder.INSTANCE;  
    }  
}
  1. 枚举
    优点: 这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
    这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
public enum Singleton {  
    INSTANCE;   
}

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

常用代码片段

性能比较好的单例写法

片段作为 Android 中的单例

单例片段或保存网页视图状态

你熟悉的设计模式都有哪些?写出单例模式的实现代码

单例模式以及静态代码块