单例模式创建方式

单例模式是一种常用的设计模式。其主要目的是确保某一个类只有一个实例存在。以下列出了几种创建单例模式的方式和它们各自的缺点:

1. 饿汉式 (Eager Instantiation)

java 复制代码
public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

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

优点: 线程安全,写法简单,在类加载的时候就实例化。

缺点: 可能存在资源浪费,如果单例没有在使用,但类已经加载,则单例对象会被初始化。

2. 懒汉式 (Lazy Instantiation)

java 复制代码
public class Singleton {
    private static Singleton INSTANCE;

    private Singleton() {}

    public static Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

优点: 延迟实例化,只有在第一次调用 getInstance 时才创建实例。

缺点: 线程不安全,如果多线程环境下,可能会多次创建实例。

3. 懒汉式线程安全版本

java 复制代码
public class Singleton {
    private static Singleton INSTANCE;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton();
        }
        return INSTANCE;
    }
}

优点: 解决了线程安全问题。

缺点: 每次调用 getInstance 方法时都需要进行同步,降低了效率,同步是在整个方法上,而不是只同步临界区。

4. 双重检查锁定 (Double-Check Locking) 线程安全版

java 复制代码
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;
    }
}

优点: 解决了线程安全问题并且锁住的临界区更小,只有单例为 null 时才会进行同步。

缺点 : 可能存在指令重排序问题,INSTANCE = new Singleton(); 可能被拆分为多条指令,必须加入 volatile 防止指令重排。

5. 静态内部类 (Static Nested Class)

java 复制代码
public class Singleton {
    private Singleton() {}

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

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

优点: 懒加载,线程安全,扩展性强(对反射安全)。内部类只有在外部类被调用才加载,产生INSTANCE实例,又不用加锁。

缺点: 相比饿汉式来说,可能存在一些性能上的差异。

6. 枚举 (Enum)

java 复制代码
public enum Singleton {
    INSTANCE;

    public void someMethod() {
        // ...
    }
}

优点: 使用这种方式定义的单例几乎是不可破坏的,它不仅能够防止多次实例化,而且还能够防止反射和序列化导致单例的破坏。

缺点: 不适合所有的场景,因为枚举提供了一种单一类型,不能与继承很好地结合使用。

以上是单例模式的几种实现方式及各自的优缺点。单例模式在某些情况下对于保证全局唯一的对象非常重要,但在设计和实现中也需要注意避免其可能导致的资源浪费和线程安全问题。

相关推荐
GGBondlctrl2 天前
【JavaEE初阶】深入解析单例模式中的饿汉模式,懒汉模式的实现以及线程安全问题
单例模式·设计模式·饿汉模式·懒汉模式·懒汉模式线程安全问题
清风拂山感2 天前
设计模式之单例模式
javascript·单例模式·设计模式
陌上之殇2 天前
C++实现单例模式
c++·单例模式
冷白白2 天前
【C++】单例模式
开发语言·c++·单例模式·c
枪哥玩转嵌入式3 天前
大佬,简单解释下“嵌入式软件开发”和“嵌入式硬件开发”的区别
单片机·单例模式·51单片机
It'sMyGo3 天前
js设计模式-工厂模式 单例模式 观察者模式 发布订阅模式 原型模式 代理模式 迭代器模式
观察者模式·单例模式·设计模式
我与岁月的森林4 天前
继承实现单例模式的探索(二)
单例模式·c#
小狗爱世界4 天前
常用设计模式之单例模式、策略模式、工厂模式
单例模式·设计模式·策略模式
湖南罗泽南4 天前
设计模式之单例模式
单例模式·设计模式
还算善良_4 天前
【设计模式】单例模式
java·单例模式·设计模式