我有另一个面试问题。我觉得这很愚蠢,但也许有些东西我不知道了。问题是这是哪个GoF模式(答案:单身),如果有任何问题,我如何解决它们。
我没有看到任何问题。我提到这从未被释放过,我希望从这种模式中获得。这就是我所说的。我错过了什么吗?
public class Class1
{
private static Class1 oInstance = null;
private Class1() { }
public static Class1 GetInstance()
{
if (oInstance == null)
{
oInstance = new Class1();
}
return oInstance ;
}
}
答案 0 :(得分:16)
线程安全 - 如果从竞争线程调用GetInstance(),则可以创建多个实例。
答案 1 :(得分:13)
请参阅:An obvious singleton implementation for .NET?
在实施Singleton模式时,您需要考虑多个问题。
以下是您可以遵循的良好通用模式。它的线程安全,密封,使用属性和延迟instaniates单身。
public sealed class Singleton
{
static class SingletonCreator
{
// This may seem odd: read about this at: http://www.yoda.arachsys.com/csharp/beforefieldinit.html
static SingletonCreator() {}
internal static readonly Singleton Instance = new Singleton();
}
public static Singleton Instance
{
get { return SingletonCreator.Instance; }
}
}
答案 2 :(得分:6)
其他人提到线程安全。还有一个事实是他们忘记将其标记为sealed
,因此您可以继承它并以这种方式创建多个实例。
答案 3 :(得分:3)
您在多线程代码中存在潜在的竞争条件。在另一个线程上的构造函数完成之前,两个线程都可以通过null检查,这样两个线程都可能最终构造该类。
答案 4 :(得分:3)
代码不是线程安全的。要做到这一点你需要这样做:
public class Class1
{
private static Class1 oInstance = null;
private Class1() { }
public static Class1 GetInstance()
{
if (oInstance == null)
{
lock(typeof(Class1))
{
if (oInstance == null)
{
oInstance = new Class1();
}
}
}
return oInstance ;
}
}
这是懒惰加载实例的最有效方式,因为当怀疑实例不会被实例化以用于下一次调用时,它只会很难锁定(可能很昂贵)。在锁定中再次检查一次确保它只会被实例化一次。
答案 5 :(得分:1)
如果您有多线程应用程序,则存在潜在问题。如果两个线程同时请求,这可能导致构造多个实例。
我会在Singletons in C#上查看此页面。它详细地显示了问题,以及更好的选择。
答案 6 :(得分:0)
以下的解决方案是什么?
public class Class1
{
private static Class1 oInstance = new Class1();
private Class1() { }
public static Class1 GetInstance()
{
return oInstance ;
}
}
答案 7 :(得分:0)
不要在那家公司工作。单例模式不是常用模式,它在纯OO系统中的适用性值得怀疑。如果您需要将其重新转换为正常构造的对象,则撤消单例模式是一个巨大的问题。
答案 8 :(得分:0)
缺少线程安全性,this page解释得非常好。