私有构造函数和实例 - 多选

时间:2014-03-09 12:46:09

标签: java singleton

我想找出以下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

  • 构造函数是私有的,无法调用

  • 值可以被垃圾收集,并且可以调用getInstance 返回垃圾数据

2 个答案:

答案 0 :(得分:4)

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() {
    }
}

答案 1 :(得分:3)

如果发生某些竞争条件,可能(可能意外地)创建多个实例(每个JVM)。

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

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

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

另见这里的评论

Singleton pattern with combination of lazy loading and thread safety

singleton pattern in java. lazy initialization

所以我会说这是一个糟糕的问题,你可以将MC作者砸在头上,因为:

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

=>是的,正如上面的讨论,但这可能不是问题的作者所想到的

  • 永远不会创建Gingleton

=>错误,好吧,{x = 1}}永远不会在此代码段中调用=>不,没有创建实例。但是作者可能会想到我们可以调用这种方法,在这种情况下答案是肯定的

  • 构造函数是私有的,无法调用

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

  • 值可以被垃圾收集,并且对getInstance的调用可能会返回垃圾数据
啊,这个说法至少是清楚的。不,静态字段不会被垃圾收集,您可以依赖它的值。