最近,在接受以下代码的采访时,我被问及与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() {
}
}以下是这个问题的选项
以上哪一种选择是正确的?为什么?
发布于 2013-03-15 05:25:02
这是一个单例模式
Singleton模式的思想是只有一个类的可用实例。因此,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从内存中读取它,而不是在缓存中设置它。
同步语句或方法帮助并发性。
了解有关二次检查锁定的更多信息,这是“延迟初始化”单例的情况。
发布于 2013-03-15 05:24:43
面试官基本上是想检查一下你对Singleton模式的了解。这个模式能打破吗?是的。检查这或google -当单例不是单例时。
最好的方法是按照约书亚·布洛赫的建议使用基于Enum的Singleton。
发布于 2013-03-15 05:34:18
可以创建多个Bolton实例。
由于上述代码中缺少同步,此选项是正确的。
假设两个线程同时检查null,两个线程都会发现值为null,两者都将调用构造函数(该构造函数驳斥单例)。
此外,这里还有其他问题,即使两个线程不一起检查null,但假设一个线程调用了构造函数;但是构造函数在构造对象之前不会返回(假设对象的创建成本很高,需要时间),所以直到构造函数返回其他线程时,才可能检查null条件,并且仍然会发现对象作为对象还没有构造。
这种情况下,某些先决条件被称为检查,然后行动,这是罪魁祸首的种族。
对于单身人士,有两种标准正在使用:
更新:这里的是另一篇讨论二次检查锁定的伟大文章
https://stackoverflow.com/questions/15425282
复制相似问题