我最近在接受以下代码的采访时被问及与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() {
}
}
以下是此问题的选项
- 可以创建多个博尔顿实例
- 永远不会创建博尔顿
- 构造函数是私有的,无法调用
- 可以对值进行垃圾回收,并且对getInstance的调用可能会返回垃圾数据
醇>
以上哪个选项是正确的?为什么?
答案 0 :(得分:8)
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方法时调用内部构造函数初始化,然后回答将是单实例将被创建。