单例模式7种实现
单例模式7种实现
- 1. 懒汉式(线程不安全)
- 2. 懒汉式(线程安全,同步方法)
- 3. 懒汉式(线程安全,双重校验锁)
- 4. 饿汉式(线程安全)
- 5. 静态内部类方式(线程安全)
- 6. 枚举方式(本质上是最好的单例实现方式)
1. 懒汉式(线程不安全)
public class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
缺点:在多线程环境下,如果多个线程同时进入getInstance()方法,可能会创建多个实例。
2. 懒汉式(线程安全,同步方法)
public class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}
缺点:每次调用getInstance()方法时都需要进行同步,这会导致性能问题。
3. 懒汉式(线程安全,双重校验锁)
public class Singleton {private volatile static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}
优点:这种方式兼具了懒加载和线程安全,同时减少了不必要的同步开销。volatile关键字确保了多线程环境下的可见性。
4. 饿汉式(线程安全)
public class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}
}
优点:这种方式比较简单,在类加载时就完成了初始化,避免了线程同步问题。但它是饿汉式的,即在类加载时就创建了实例,即使没有用到这个实例。
5. 静态内部类方式(线程安全)
public class Singleton {private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}private Singleton() {} // 私有构造函数防止外部直接创建对象实例 public static Singleton getInstance() { // 提供全局访问点 return SingletonHolder.INSTANCE; // 返回内部类实例 }
}
优点:这种方式也是懒加载的,同时保证了线程安全,且写法优雅。当getInstance()方法被调用时,才加载SingletonHolder类,从而创建Singleton的实例。这种方式利用了Java的类加载机制来保证初始化实例时的线程安全。
6. 枚举方式(本质上是最好的单例实现方式)
public enum Singleton { // 使用枚举类型实现单例模式 INSTANCE; // 枚举元素本身就是单例 public void someMethod() { // 可以添加自己的方法 // ... }
}
优点:这种方法由JVM从根本上提供保障,简单高效,而且自动支持序列化机制。使用枚举可以防止反序列化重新创建新的对象。这是实现单例模式的最佳方法。 枚举方式是处理单例模式的推荐方法,因为它提供了更强的保证。枚举类型的构造器默认是私有的,所以无法通过其他类进行实例化,同时又保证了序列化时的单例特性。此外,枚举类型是线程安全的,并且在任何情况下都不会被破坏其单例性。因此,它是实现单例的最佳方式。