Java线程单例模式

在 Java 编程中,单例模式是一种常见的设计模式,它的目的在于确保一个类仅有一个实例,并提供一个全局访问点。单例模式可以通过多种方式实现,其中线程安全的单例实现更是非常重要,尤其是在多线程环境下。本文将重点介绍 Java 中的线程安全单例模式及其实现方式。

单例模式的实现方式

1. 饿汉式单例

最简单的实现方式是饿汉式单例,在类加载的时候就实例化对象。这种方式是线程安全的,但比较浪费内存,因为无论是否会用到实例,都会创建一个对象。

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

    private HungrySingleton() {}

    public static HungrySingleton getInstance() {
        return INSTANCE;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
2. 懒汉式单例

懒汉式单例在需要的时候才创建对象。为了确保线程安全,可以使用 synchronized 关键字来修饰 getInstance 方法。但这样会降低性能,因为每次调用都需要进行同步。

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
3. 双重检查锁定(DCL)

双重检查锁定是懒汉式单例改进的一种实现,它减少了 synchronized 代码块的执行次数,提高效率。

public class DoubleCheckedLockingSingleton {
    private static volatile DoubleCheckedLockingSingleton instance;

    private DoubleCheckedLockingSingleton() {}

    public static DoubleCheckedLockingSingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedLockingSingleton.class) {
                if (instance == null) {
                    instance = new DoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
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;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

关系图

在上述不同的单例实现之间存在着明显的关系。请参考以下 ER 图:

SINGLETON string name string type HUNGRY LAZY DOUBLE_CHECKED_LOCKING STATIC_INNER_CLASS implements implements implements implements

在这个关系图中,每个单例模式均为 SINGLETON 的一个实现。

小结

线程安全的单例模式在 Java 编程中占据重要位置,合理选择单例实现方式将极大提高系统的性能与安全性。上述讨论的几种单例模式各有优缺点,开发者需根据具体业务场景和需求做出选择。值得注意的是,在 Java 8 以后的版本中,还可以使用枚举来实现更简单的单例模式。

通过了解和运用线程单例模式,您可以构建出更为高效、健壮的 Java 应用程序,以满足日益增加的高并发要求。希望这篇文章能对您理解 Java 线程单例模式有所帮助!