单身模式面试

时间:2013-03-15 05:19:05

标签: java singleton

我最近在接受以下代码的采访时被问及与java相关的问题,因为我对java很新,而且几乎不用Java代码,所以我真的不知道下面的代码是做什么的。

问题是     使用以下代码选择描述最糟糕事情的选项:

public class Bolton {
    private static Bolton INST = null;

    public static Bolton getInstance()
    {
        if ( INST == null )
        {
            INST = new Bolton();
        }
        return INST;
    }

    private Bolton() {
    }
}

以下是此问题的选项

  
      
  1. 可以创建多个博尔顿实例
  2.   
  3. 永远不会创建博尔顿
  4.   
  5. 构造函数是私有的,无法调用
  6.   
  7. 可以对值进行垃圾回收,并且对getInstance的调用可能会返回垃圾数据
  8.   

以上哪个选项是正确的?为什么?

8 个答案:

答案 0 :(得分:8)

这是Singleton Pattern

Singleton Pattern的想法是只有一个类的可用实例。因此,constructor设置为private,在这种情况下,类维护一个getInstance()方法,该方法可以调用此类中的现有实例变量INST,也可以创建一个新的执行程序。答案可能是1,因为它不是线程安全的。它可能会被混淆为3,我之前已经说过了,但这在技术上是设计上的,所以实际上并不是一个缺陷。

以下是来自维基百科的延迟初始化,线程安全的单例模式的示例:

public class SingletonDemo {

    private static volatile SingletonDemo instance = null;

    private SingletonDemo() {  } 

    public static SingletonDemo getInstance() {
        if (instance == null) {
            synchronized (SingletonDemo.class){
                if (instance == null) {
                    instance = new SingletonDemo();
                }
            }
        }
        return instance;
    }

}

将实例变量设置为volatile会告诉Java从内存中读取它并且不将其设置在缓存中。

Synchronized statements or methods帮助concurrency

阅读有关double checked locking的更多内容,这是“懒惰初始化”单例

的情况

答案 1 :(得分:2)

采访者基本上想检查你的单身人士模式的知识。模式可以被打破吗?答案是肯定的。当单身人士不是单身人士时,请检查this或谷歌。

最佳课程是使用Joshua Bloch建议的Enum based Singleton

答案 2 :(得分:2)

  

可以创建多个博尔顿实例

由于上述代码中缺少同步,此选项是正确的。

假设两个线程同时检查null,并且两个线程都会发现值为null,并且两者都会调用构造函数(反驳单例)

此外还有其他问题,即使两个线程不一起检查null,但假设一个线程调用构造函数;但构造函数不会返回,直到构造对象(假设对象创建成本高,需要时间),所以直到构造函数返回其他一些线程可能会检查null条件并仍然找到对象为{{ 1}}因为对象尚未构建。

这种情况下,某些先决条件被称为 check-then-act ,这是Race的罪魁祸首。

对于单身人士,有两种标准正在使用:

<强>更新 这是另一篇讨论double checked locking

的精彩文章

答案 3 :(得分:1)

getInstance()方法应该同步,否则如果多个线程同时调用getInstance(),则可以创建许多实例。所以我会选择选项1。

答案 4 :(得分:1)

当我们想要只有这个类的一个对象时,我们使用Singleton Pattern,它将在每个地方使用。因此,要限制类创建许多对象,我们应该使用private作为此类的构造函数。并创建一个public函数来返回此类的对象。

public class MethodWin {
    private int isLoggedOn=0;
    private static MethodWin objectMethodWin = new MethodWin();
    private MethodWin() { }
    public static MethodWin getInstance() {
        return objectMethodWin;
    }
    public void setIsLoggedOn(int value) {
       this.isLoggedOn=value;
    }
    public int getIsLoggedOn() {
       return this.isLoggedOn;
    }
}

因此,当我们需要创建此对象时,我们应该:

MethodWin meth = MethodWin.getInstance();

答案 5 :(得分:0)

原始答案是只创建了一个博尔顿实例。

答案 6 :(得分:0)

通过反射,即使构造函数是私有的,我们也可以创建许多对象。
在多线程环境中,有可能创建多个实例。
通过序列化,有机会创建多个对象。

答案 7 :(得分:0)

简单答案是2) A Bolton will never be created,因为当你创建实例时,构造函数将在调用getInstance方法时调用内部构造函数初始化,然后回答将是单实例将被创建。

相关问题