单例模式应该是我们接触到的最简单的设计模式,结构简洁,代码短小,实现起来非常容易。它确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式包含如下角色:

  • Singleton:单例
    在单例类的内部实现只生成一个实例,同时它提供一个静态的工厂方法,让客户可以使用它的唯一实例;为了防止在外部对其实例化,将其构造函数设计为私有。
类图

单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

单例模式的实现方式有饿汉式、懒汉式、静态内部类等,菜鸟教程上的单例模式总结得就很全面,要根据实际情况选择合适的方式。

我主要使用下面三种实现方式,双重校验锁和静态内部类保证了线程安全和懒加载;饿汉式做到了线程安全,在类加载时就进行实例化。

1. 双重校验锁:

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;  
    }  
}  

2. 静态内部类:

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

3. 饿汉式:

public class Singleton {  
    private static Singleton instance = new Singleton();  
    
    private Singleton (){
        
    }  
    
    public static Singleton getInstance() {  
        return instance;  
    }  
}  

  • 优点: 提供了对唯一实例的受控访问并可以节约系统资源。
  • 缺点: 由于缺少抽象层而难以扩展,而且单例类职责过重。
  • 使用场景: 系统只需要一个实例对象;客户调用类的单个实例只允许使用一个公共访问点。