java - 如何以正确的方式编写单例?

标签 java multithreading design-patterns singleton

今天在我的面试中,一位面试官让我写一个 Singleton 类。我的回答是

public class Singleton {

    private static Singleton ref;

    private Singleton() {
    }

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

他突然告诉我这是写类(class)的老方法。任何人都可以帮助我为什么他这样说。

最佳答案

创建单例时我首先想到的是enum。我一般使用枚举来实现单例:

enum Singleton {
    INSTANCE;
}

使用枚举获得的一个好处是序列化。

对于单例类,您必须确保序列化和反序列化不会通过实现 readResolve() 方法来创建新实例,而枚举则不是这样。

使用类你应该像这样创建单例:

public final class Singleton implements Serializable {
    // For lazy-laoding (if only you want)
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton() {
        if (SingletonHolder.INSTANCE != null) {
            // throw Some Exception
        }
    }

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

    // To avoid deserialization create new instance
    @SuppressWarnings("unused")
    private Singleton readResolve() {
        return SingletonHolder.INSTANCE;
    }
}

关于java - 如何以正确的方式编写单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18855375/

相关文章:

java - 如何解析所有子字段并在 Firebase 数据库中找到我需要的内容?

c# - 在 WPF 中是否有使用后台 worker 的替代方法?

c++ - 类层次结构设计,避免从基类到派生类的向下转型

用于扩展任意标准符合分配器的 C++ 设计模式

c# - 如何适本地设计数据访问层?

java - 如何使用 Jsoup 进行多线程处理

java - 为什么 Android 的 AsyncTask 没有实现 Future?

c - 使用多线程优化硬盘读写功能的速度

android - RxJava Android - 在适当的线程上加载缓存显示数据

java - Maven JAXB 插件的区别