任何人都可以在实现Singleton Design Pattern的Java / C#代码片段中识别问题。
有人能在这个片段的实现中找到我的缺陷吗?
class Singleton{
public static Singleton Instance() {
if (_instance == null)
_instance = new Singleton();
return _instance;
}
protected Singleton() {}
private static Singleton _instance = null;
}
答案 0 :(得分:9)
答案 1 :(得分:3)
正如Kieren所说,它不是线程安全的......并且也你允许类派生它,这意味着它不是真正的单例:
public class SingletonBasher : Singleton
{
}
Singleton x = Singleton.Instance();
Singleton y = new SingletonBasher();
x
和y
应该是无效的,并且它们都是非空的 - 它违反了单身的概念。
(是的,我也推荐my article on singleton implementations:)
答案 2 :(得分:2)
实现单例的更好方法(如Joshua Bloch的Effective Java)是使用枚举:
enum Singleton {
INSTANCE();
private Singleton() {
....
}
}
如果你坚持自己的方法,你还需要做三件事:
答案 3 :(得分:1)
enum A { A; }
答案 4 :(得分:0)
如果您处于多线程环境中,则两个不同的线程可能会进入if块,然后它们都将创建一个新实例。添加锁定:
class Singleton{
public static Singleton Instance() {
if (_instance == null) {
lock(typeof(Singleton)) {
if (_instance == null) {
_instance = new Singleton();
}
}
}
return _instance;
}
protected Singleton() {}
private static Singleton _instance = null;
}
答案 5 :(得分:0)
以上所有答案都是正确的。
在单例设计模式中,您不应允许其他人为单例类创建实例。你必须拥有自己的权利。另一个实例可以请求您使用singleton的实例。所以构造函数应该/必须是私有的。
在您的示例中,您将其设置为受保护,在这种情况下,如果您扩展单例类,则可以从其他实例创建实例。不应该提供这种可能性。
在您的代码段中将构造函数设置为私有,然后在其单例类中创建。
答案 6 :(得分:0)
它不是线程安全的。
您可以通过预初始化以不同的方式实现:
private static Singleton _instance = new Singleton();
public static Singleton Instance()
{
return _instance;
}
此方法是线程安全的,因为您只返回方法中的实例。