首页常见问题正文

用Java写一个线程安全的单例模式(Singleton)?

更新时间:2023-09-12 来源:黑马程序员 浏览量:

IT培训班

  要编写一个线程安全的单例模式(Singleton)类,我们可以使用以下方法之一。这两种方法都确保只有一个实例被创建,并且在多线程环境中安全使用。

  方法一:懒汉式(Lazy Initialization)

  在懒汉式中,实例在第一次被请求时才会被创建。

public class Singleton {
    private static Singleton instance;

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

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

  这种方法使用了synchronized关键字来确保线程安全,但它会引入性能开销,因为每次调用getInstance方法都会进行同步。
1694482375300_线程安全的单例模式.jpg

  方法二:双重检查锁定(Double-Checked Locking)

  双重检查锁定允许我们在没有同步的情况下创建实例,只有在实例不存在时才进行同步。

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;
    }
}

  在这个版本中,我们使用了volatile关键字来确保instance变量对所有线程可见,避免了可能的重排序问题。

  使用上述任何一种方法都可以创建一个线程安全的单例模式类。如果我们使用Java 5或更高版本,强烈建议使用双重检查锁定方法,因为它在性能上有一些优势。但要注意,这些示例中的单例模式是懒加载的,只有在需要时才会创建实例。如果我们需要在应用程序启动时立即创建实例,可以使用饿汉式(Eager Initialization)方法。

分享到:
在线咨询 我要报名
和我们在线交谈!