📜  防止从线程创建单例实例 - Java (1)

📅  最后修改于: 2023-12-03 14:58:38.584000             🧑  作者: Mango

防止从线程创建单例实例 - Java

在Java中,单例模式是非常常见的一种设计模式,它用于确保一个类只有一个实例,并且提供该实例的全局访问点。然而,在多线程环境下,单例模式可能会遇到问题,因为多个线程有可能同时创建多个实例,破坏了单例的原则。

一种解决方案是使用synchronized关键字来确保线程安全。但是,这会带来性能问题,因为每次访问单例实例时,都需要进行同步。

更好的解决方案是使用“双检锁”(double-checked locking)技术来确保只有一个线程可以创建单例实例。这种技术利用了volatile关键字的特殊语义来确保同步。

以下是一个线程安全的单例模式示例代码:

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

在这个示例中,getInstance方法首先检查instance是否已经被创建了,如果没有,再加锁进入同步块来进行创建。但是,在同步块中再次检查instance是否为null,这是为了确保在另一个线程同时进入同步块时,不会再次创建实例。

值得注意的是,instance需要被声明为volatile,因为在Java中,JVM有可能会重排序指令,如果不使用volatile关键字,可能会在一个线程还没有完成实例创建之前,另一个线程就已经使用了未完全初始化的实例。

总之,使用“双检锁”技术是一种非常高效且线程安全的创建单例实例的方式。记住要使用volatile关键字来确保同步,否则可能会遇到未定义的行为。