Jupyter AI

10 Java设计模式之单例模式

📅 发表日期: 2024年8月10日

分类: Java 高级

👁️阅读: --

在前一篇中,我们探讨了Java 8的新特性,特别是Optional类,它帮助我们有效地处理可能为null的值,从而减小了出现NullPointerException的风险。而在本篇文章中,我们将深入理解Java设计模式中的单例模式。这是一个非常重要的设计模式,常用于确保某个类只有一个实例,并提供全局访问点。

什么是单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点。这个模式通常用于控制对共享资源的访问,例如数据库连接、线程池等。

在Java中,单例模式的实现有多种方式,下面我们将介绍最常用的几种。

单例模式的实现方式

1. 饿汉式单例

饿汉式单例是在类加载时立即实例化Singleton类的实例。当这个类被使用时,实例已存在。

实现代码

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

    private Singleton() {
        // 私有构造函数,防止外部实例化
    }

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

使用示例

public class Main {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        System.out.println(singleton1 == singleton2); // 输出 true
    }
}

2. 懒汉式单例

懒汉式单例在需要时才创建实例。为了避免多线程环境下的竞争,通常会使用synchronized关键字来确保线程安全。

实现代码

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {
        // 私有构造函数,防止外部实例化
    }

    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

使用示例

public class Main {
    public static void main(String[] args) {
        LazySingleton lazySingleton1 = LazySingleton.getInstance();
        LazySingleton lazySingleton2 = LazySingleton.getInstance();

        System.out.println(lazySingleton1 == lazySingleton2); // 输出 true
    }
}

3. 双重检查锁定单例

为了提高懒汉式单例的性能,可以使用双重检查锁定(Double-Check Locking)进行优化。这样,只有在实例为空时,才会 synchronized,以降低了性能开销。

实现代码

public class DoubleCheckSingleton {
    private static volatile DoubleCheckSingleton instance;

    private DoubleCheckSingleton() {
        // 私有构造函数,防止外部实例化
    }

    public static DoubleCheckSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

使用示例

public class Main {
    public static void main(String[] args) {
        DoubleCheckSingleton doubleCheckSingleton1 = DoubleCheckSingleton.getInstance();
        DoubleCheckSingleton doubleCheckSingleton2 = DoubleCheckSingleton.getInstance();

        System.out.println(doubleCheckSingleton1 == doubleCheckSingleton2); // 输出 true
    }
}

4. 静态内部类单例

通过一个静态内部类来实现单例模式,利用JVM的类加载机制来达到懒加载和线程安全的效果。

实现代码

public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {
        // 私有构造函数,防止外部实例化
    }

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

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

使用示例

public class Main {
    public static void main(String[] args) {
        StaticInnerClassSingleton singleton1 = StaticInnerClassSingleton.getInstance();
        StaticInnerClassSingleton singleton2 = StaticInnerClassSingleton.getInstance();

        System.out.println(singleton1 == singleton2); // 输出 true
    }
}

总结

单例模式在Java中具有广泛的应用场景,它可以有效地控制实例的创建,节省资源并简化管理。在实际使用中,应根据具体的需求选择合适的单例模式实现方式。接下来,我们将对比单例模式与工厂模式,以更好地理解这两种设计模式在实际开发中的应用。

通过掌握单例模式,您将能够在需要确保某个类只有一个实例时做出正确的设计决策,为接下来的工厂模式打下良好的基础。