这个单例设计模式是否正确?

时间:2013-02-15 08:29:09

标签: java design-patterns singleton

这个单身设计模式是否正确?我的意思是当它是静态的并且方法是同步的时,检查对象是否为空的需要是什么。

public class MySingleton {

    int val = 10;
    private static final MySingleton singleton = new MySingleton();

    private MySingleton() { }

    public static synchronized MySingleton getSingleton() {
        return singleton;
    }
}

3 个答案:

答案 0 :(得分:8)

您无需使方法同步。变量在静态初始化程序中初始化的事实就足够了。此外,您的val变量几乎肯定应该是私有的......

当你想要一个同步的方法并且想要一个静态初始化器时,通常会使用双重检查的锁定模式(带有无效性检查) 。 (在我看来,几乎在所有情况下它都是不必要的复杂和脆弱。)

另一种选择是使用枚举:

public enum MySingleton {
    INSTANCE;

    private int val = 10;

    // Presumably something to use val
}

使用枚举强制执行单例,甚至在序列化时使其正确。这也是一种非常简单的方法,没有实际的代码:)另一方面,从来没有感觉完全对我...

答案 1 :(得分:2)

最好的模式是Joshua Bloch在他的书“Effective Java”中使用Enum:

public enum MySingleton {
    INSTANCE;

    public void doSomething() {

    }
}

引用这本书:

"这种方法在功能上等同于公共字段方法,除了它更简洁,免费提供序列化机制,并提供防止多个实例化的铁定保证,即使面对复杂的序列化或反射攻击。虽然这种方法尚未被广泛采用,但单元素枚举类型是实现单例的最佳方式。"

答案 2 :(得分:2)

您可以这样做,但在许多情况下,您可以使用“延迟评估” - 您在第一次请求时创建实例:

public class MySingleton {

    private static MySingleton singleton = null

    private MySingleton() { }

    public static synchronized MySingleton getSingleton() {
        if (singleton == null) {
            singleton = new MySingleton();
        }
        return singleton;
    }
}