【问题标题】:Private constructor and instances - Multiple choice私有构造函数和实例 - 多项选择
【发布时间】:2014-03-09 12:46:08
【问题描述】:

我正在尝试找出以下 MC 问题的答案。我曾尝试在谷歌上寻找答案,但人们似乎对这个问题有不同的答案。有人可以解释他们的答案。

public class Gingleton {
    private static Gingleton INSTANCE = null;

    public static Gingleton getInstance()
    {
        if ( INSTANCE == null )
        {
            INSTANCE = new Gingleton();
        }
        return INSTANCE;
    }

    private Gingleton() {
    }
}
  • 可以创建多个 Gingleton 实例(我的选择)

  • 永远不会创建 Gingleton

  • 构造函数是私有的,不能调用

  • value 可以被垃圾回收,并且对 getInstance 的调用可能 返回垃圾数据

【问题讨论】:

  • 您可以轻松运行测试,看看您的答案是否正确。
  • +1 为Gingleton :)
  • “我认为这是正确的,因为构造函数是私有的”——很可能不是正确的推理。
  • 如何创建两个或多个实例? (你的答案)
  • @LutzHorn 不,我认为只有一个是正确的

标签: java singleton


【解决方案1】:

getInstance() 中的新实例创建不会以任何方式同步,因此在多线程环境中可能会创建多个实例。为确保只有一个实例,您应该这样做:

public class Gingleton {

    // volatile
    private static volatile Gingleton INSTANCE = null;

    public static Gingleton getInstance()
    {
        if ( INSTANCE == null )
        {
            synchronized (Gingleton.class) {  // Synchronized
                if ( INSTANCE == null )
                {
                    INSTANCE = new Gingleton();
                }
            }
        }
        return INSTANCE;
    }

    private Gingleton() {
    }
}

【讨论】:

【解决方案2】:

如果出现某种竞争条件,可能(可能是意外地)创建多个实例(每个 JVM)。

此代码实际上反映了“惰性单例模式”,即目的是每个 JVM 只有一个实例,在第一次访问时创建。

=> 乍一看,我们只能拥有它的一个实例。但是,由于代码不同步,这部分代码可能会在多线程环境中并行执行多次。

if ( INSTANCE == null )
    {
        INSTANCE = new Gingleton();
    }

参见此处的 cmets

Singleton pattern with combination of lazy loading and thread safety

singleton pattern in java. lazy initialization

所以我会说这是个坏问题,你可以猛烈抨击 MC 作者的头脑,因为:

  • 可以创建多个 Gingleton 实例(我的选择)

=> 确实,鉴于上面的讨论,但这可能不是问题作者的想法

  • 永远不会创建 Gingleton

=> errr,好吧,getInstance() 在这个 sn-p 中从未被调用 => 不,没有创建实例。但是可能作者想到我们可以调用这个方法,在这种情况下答案是肯定的

  • 构造函数是私有的,不能调用

可以调用私有构造函数...只是不能从类外部调用。同样,作者没有制定它,但我们可以假设他或她只是“从外部”考虑这个案例

  • value可以被垃圾回收,调用getInstance可能会返回垃圾数据

啊,这个说法至少是清楚的。不,静态字段不会被垃圾回收,您可以依赖它的值。

【讨论】:

  • 我给了你我的 +1 指出选项的荒谬性。很难说出预期的“正确”答案是什么。
  • 我认为指出 getInstance() 从未被调用只是迂腐
  • @Radiodef 谢谢!读懂考官的想法确实是一门微妙的艺术:)。我个人会猜到 3,问题和多答案感觉就像我们开始学习 java 时遇到的那种事情,所以多线程可能超出了这个类的范围,重点是强调用法方法访问修饰符。
  • @DeadChex,好吧好吧,我想你是对的。我仍然觉得必须猜测检查时所期望的严格程度是令人沮丧的。
  • @Svend 我仍在反复讨论我认为预期的答案。我也开始进入#3,因为我认为这个问题应该测试访问修饰符。这是看待它并使其整体有意义的唯一方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
相关资源
最近更新 更多