单例模式

88 阅读2分钟

单例模式是一种常用的设计模式,定义为某个类全局下只能拥有一个实例。 用于在某些情况下系统只需一个对象协调系统的整体行为;

  1. 类似于任务管理器,任意时刻只能打开一个;

  2. 网站计数器,计数器的单个实例方便计数器的同步;

  3. web应用的配置文件读取,这个文件由某个单例对象进行读取,其他对象通过该单例对象获取数据。 单例模式的注意点:

  4. 构造函数私有化,防止外部类创建该类实例;

  5. 内部提供一个static方法用于返回该类的唯一实例,当类内部实例引用不为空时,返回该实例,否则创建一个实例并赋值其引用。 单例模式懒汉式:

  6. 懒汉式(仅在外部调用getInstance()方法时实例化)

public class SingleTon{
    private static SingleTon instance;
    private SingleTon();
    
    private static SingleTon getInstance(){
        if(instance == null) instance = new SingleTon();
        return instance;
    }
}

多线程情况下,假设某个线程进入if(instance == null) 分支后,还未执行初始化时其他线程也进入了该分支,此时会创建两个实例,违反了单例模式。
2.懒汉式(线程安全)

public class SingleTon{
    private static SingleTon instance;
    private SingleTon();
    
    private static Synchronized SingleTon getInstance(){
        if(instance == null) instance = new SingleTon();
        return instance;
    }
}

通过对getIntance()方法进行Sychronized加锁保证任意时刻只能有一个线程进入该代码块创建实例。
3. 饿汉式(类装载时就进行实例化)

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

通过静态常量初始化。
4.饿汉式

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

通过静态代码块初始化。
4.DCL(double check lock)

public class Singleton {

    private static volatile Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
  1. 静态内部类
public class Singleton {

    private Singleton() {}

    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }
}