什么是单例模式
- 单例模式(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;
}
}
}