实施单例设计模式[请建议]

时间:2011-08-19 09:04:08

标签: c# java design-patterns

任何人都可以在实现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;
}

7 个答案:

答案 0 :(得分:9)

答案 1 :(得分:3)

正如Kieren所说,它不是线程安全的......并且你允许类派生它,这意味着它不是真正的单例:

public class SingletonBasher : Singleton
{
}

Singleton x = Singleton.Instance();
Singleton y = new SingletonBasher();

xy应该是无效的,并且它们都是非空的 - 它违反了单身的概念。

(是的,我也推荐my article on singleton implementations:)

答案 2 :(得分:2)

实现单例的更好方法(如Joshua Bloch的Effective Java)是使用枚举:

enum Singleton {
    INSTANCE();
    private Singleton() {
       ....
    }
}

如果你坚持自己的方法,你还需要做三件事:

  • 使构造函数成为私有(如Jon Skeet的建议)
  • make _instance volatile
  • 双重锁定Instance()

答案 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;
}

此方法是线程安全的,因为您只返回方法中的实例。