Java 单例设计模式:问题

2022-09-02 21:42:12

我最近有一次采访,他问我关于单例设计模式如何实现,我告诉他,使用静态变量和静态方法,我们可以实现单例设计模式。

他似乎对答案有一半的满意,但我想知道

  1. 我们可以在Java中实现单例设计模式多少种不同的方法?
  2. Singleton Object的范围是什么,它如何在JVM中实际工作?我知道我们总是会有一个单例对象的实例,但是该对象的实际范围是什么,它是在JVM中,还是如果有多个应用程序在运行,那么它的范围是在JVM内部的每个上下文的基础上,我真的对此感到困惑,无法给出令人满意的解释?
  3. 最后,他问道,是否可以将 Singleton Object 与 Clusters 一起使用并进行解释,当我们调用 Bean Factory 来获取对象时,有没有办法让 Spring 不实现 Singleton Design Pattern?

关于单例的任何输入都会受到高度赞赏,在处理单例时要记住的主要事项是什么?

谢谢。


答案 1

有几种方法可以在Java中实现单例模式:

// private constructor, public static instance
// usage: Blah.INSTANCE.someMethod();
public class Blah {
    public static final Blah INSTANCE = new Blah();
    private Blah() {
    }
    // public methods
}

// private constructor, public instance method
// usage: Woo.getInstance().someMethod();
public class Woo {
    private static final Woo INSTANCE = new Woo();
    private Woo() {
    }
    public static Woo getInstance() {
        return INSTANCE;
    }
    // public methods
}

// Java5+ single element enumeration (preferred approach)
// usage: Zing.INSTANCE.someMethod();
public enum Zing {
    INSTANCE;
    // public methods
}

给定上述示例,每个类装入器将有一个实例。

关于在集群中使用单例...我不确定“使用”的定义是什么...面试官是否暗示在集群中创建单个实例?我不确定这是否很有意义...?

最后,在 spring 中定义非单例对象只需通过属性 singleton=“false” 来完成。


答案 2

我不同意@irreputable。

单例的作用域是它在类装入器树中的节点。它包含类装入器,任何子类装入器都可以看到单例。

了解这个范围概念非常重要,尤其是在具有复杂的类装入器层次结构的应用程序服务器中。

例如,如果在应用服务器的系统类路径上的 jar 文件中有一个库,并且该库使用单例,则该单例对于部署到应用服务器中的每个“应用”(可能)都是相同的。这可能是一件好事,也可能不是一件好事(取决于库)。

恕我直言,类加载器是Java和JVM中最重要的概念之一,而单例正好发挥了这一作用,所以我认为Java程序员“关心”是很重要的。


推荐