Java中创建线程安全的单例模式方法总结

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 如何在Java中创建线程安全的Singleton?

回答:

在Java中创建线程安全的Singleton(单例模式)有多种方法。以下是几种常见的实现方式:

1. 饿汉式(Eager Initialization)

这种方式在类加载时就创建了实例,线程安全,但不支持延迟加载。

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

    private Singleton() {
        // 私有构造函数
    }

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

2. 懒汉式(Lazy Initialization) - 同步方法

这种方式在第一次调用 getInstance() 时创建实例,线程安全,但每次调用都需要同步,性能较低。

public class Singleton {
    private static Singleton instance;

    private Singleton() {
        // 私有构造函数
    }

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

3. 懒汉式(Lazy Initialization) - 双重检查锁定

这种方式结合了懒加载和同步的优点,性能较好。

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. 静态内部类

这种方式利用了Java的类加载机制,既实现了懒加载,又是线程安全的。

public class Singleton {
    private Singleton() {
        // 私有构造函数
    }

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

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

5. 枚举方式

使用枚举类型来实现单例模式是最简单且线程安全的方式。

public enum Singleton {
    INSTANCE;

    // 可以添加其他方法
    public void someMethod() {
        // 方法实现
    }
}

总结

以上几种方式各有优缺点,选择合适的实现方式取决于具体的需求和场景。一般来说,静态内部类和枚举方式是推荐的实现方式,因为它们既简单又线程安全。