什么是单例模式
- 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建,并提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象
 
单例模式特点
- 单例类只能有一个实例
 
- 单例类必须自己创建自己的唯一实例
 
- 单例类必须给所有其他对象提供这一实例
 
单例模优缺点
优点
- 在内存里只有一个实例,减少了内存的开销
 
- 提供了对唯一实例的受控访问
 
- 避免对资源的多重占用
 
- 优化和共享资源访问
 
- ...
 
缺点
- 没有接口,难以扩展
 
- 没有接口,不能继承,一定程度上违背了“单一职责原则”,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化
 
- ...
 
常见单例模式实现
懒汉式,线程不安全
public class Singleton {
    private static Singleton singleton;
    private Singleton (){}
    public static Singleton getInstance() {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
    }
}
懒汉式,线程安全
- 线程安全
 
- 优点:第一次调用才初始化,避免内存浪费
 
- 缺点:加锁会影响效率
 
public class Singleton {
    private static Singleton singleton;
    private Singleton (){}
    public static synchronized Singleton getInstance() {
    if (singleton == null) {
        singleton = new Singleton();
    }
    return singleton;
    }
}
public class Singleton {
    private static Singleton singleton;
    private Singleton() {
    }
    public static Singleton getInstance() {
        synchronized (Singleton.class) {
            if (singleton == null) {
                singleton = new Singleton();
            }
        }
        return singleton;
    }
}
饿汉式
- 线程安全
 
- 优点:没有加锁,执行效率会提高
 
- 缺点:类加载时就初始化,浪费内存
 
public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton() {
    }
    public static Singleton getInstance() {
        return singleton;
    }
}
#静态代码块
public class Singleton {
    private static Singleton singleton = null;
    static {
        singleton = new Singleton();
    }
    private Singleton() {
    }
    public static Singleton getInstance() {
        return singleton;
    }
}
双重校验锁
- 线程安全
 
- 采用双锁机制,安全且在多线程情况下能保持高性能
 
public class Singleton {
    private static Singleton singleton = null;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
静态内部类
- 线程安全
 
- 达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用
 
- SingletonHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonHolder 类,从而实例化 instance
 
public class Singleton {
    private static class SingletonHolder {
        private static final Singleton SINGLETON = new Singleton();
    }
    private Singleton() {
    }
    public static Singleton getInstance() {
        return SingletonHolder.SINGLETON;
    }
}
内部枚举类
public class Singleton {
    private Singleton() {
    }
    public static Singleton getInstance() {
        return SingletonEnum.INSTANCE.getInstance();
    }
    public enum SingletonEnum {
        INSTANCE;
        private Singleton singleton = null;
        private SingletonEnum() {
            singleton = new Singleton();
        }
        public Singleton getInstance() {
            return singleton;
        }
    }
}