单例模式
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了一个访问该实例的全局访问点。
实现单例模式的关键点是私有化该类的构造方法,以防止其他对象创建该类的实例,同时提供一个公共的静态方法来返回该类的唯一实例。
最常用的方法。
以下是几个常见的单例模式的实现示例:
-
饿汉式单例模式
在该模式下,实例化对象是在类加载时完成的,因此不存在多线程下的竞争问题。当类被加载时,类加载器负责对静态成员进行初始化,此时静态成员instance会被初始化为其唯一实例,是线程安全的。该模式适用于单例对象不需要延迟加载的情况。
public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
-
懒汉式单例模式
在该模式下,单例对象在第一次被访问时才会被创建出来。该模式适用于单例对象需要延迟加载的情况,但是线程不安全。
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
-
双重检查锁定单例模式
该模式结合了懒汉式单例模式和同步锁机制的优点,通过双重检查锁定来保证线程安全。
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
-
静态内部类单例模式
该模式利用了Java的静态内部类特性,在内部类中实例化单例对象,从而保证单例对象的唯一性和延迟加载。
public class Singleton { private Singleton() {} private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
-
枚举实现单例模式
- 线程安全:枚举类实例的创建是线程安全的,而且在任何情况下都是单例的。
- 避免反射攻击:由于枚举类的构造函数是私有的,因此无法通过反射机制调用构造函数来创建枚举类实例。
- 避免序列化问题:枚举类天生就是可以序列化的,因此可以避免通过序列化和反序列化破坏单例模式。
public enum Singleton { INSTANCE; // 定义一个枚举元素,它就代表了 Singleton 的一个实例 public void doSomething() { // do something } }
在使用时,可以通过
Singleton.INSTANCE
来获取实例,例如:Singleton singleton = Singleton.INSTANCE; singleton.doSomething();