欢迎访问宙启技术站
智能推送

Java函数实现单例模式,如何做到线程安全?

发布时间:2023-07-06 12:03:30

在Java中,实现线程安全的单例模式可以通过以下几种方式:

1. 饿汉式(早期初始化):

这种方式下,单例对象在类加载的时候就创建好了,所以是线程安全的。实现方式很简单,就是在类中定义一个私有的静态成员变量,并在类加载时就初始化这个成员变量。

public class Singleton {
    private static Singleton instance = new Singleton();
    
    private Singleton() {
    }
    
    public static Singleton getInstance() {
        return instance;
    }
}

2. 懒汉式(延迟初始化):

这种方式下,单例对象在 次使用时才创建,通过使用同步锁来保证多个线程安全地访问。

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

上述方式虽然实现了线程安全,但每次调用getInstance()方法时都需要进行同步,会造成不必要的性能开销。

3. 双重检验锁:

该方式在懒汉式的基础上进行了改进,只在 次创建实例时进行同步,之后的调用就无需再进行同步。在方法内部使用两次判空的原因是: 次判空是为了避免不必要的同步,第二次判空是为了确定只有一个线程能够创建实例。

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

4. 静态内部类:

这种方式通过使用静态内部类来实现延迟初始化,由于静态内部类只会在 次被使用时才进行加载,且类加载过程是线程安全的,所以是线程安全的。

public class Singleton {
    private Singleton() {
    }
    
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

需要注意的是,以上提到的方式都可以实现线程安全的单例模式,但并不是所有的方式都适用于所有的场景,需要根据具体的需求选择合适的实现方式。