2

这种单例设计模式正确吗?我的意思是当它是 static 并且方法是 synchronized 时,需要检查对象是否为 null 。

public class MySingleton {

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

    private MySingleton() { }

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

3 回答 3

8

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

当您想要同步方法并且想要静态初始化程序时,通常使用双重检查锁定模式(带有无效性检查)。(在我看来,它几乎在所有情况下都过于复杂和脆弱。)

另一种选择是使用枚举:

public enum MySingleton {
    INSTANCE;

    private int val = 10;

    // Presumably something to use val
}

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

于 2013-02-15T08:32:27.530 回答
2

最好的模式是 Joshua Bloch 在他的《Effective Java》一书中使用 Enum 给出的模式:

public enum MySingleton {
    INSTANCE;

    public void doSomething() {

    }
}

引用本书:

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

于 2013-02-15T08:34:29.933 回答
2

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

public class MySingleton {

    private static MySingleton singleton = null

    private MySingleton() { }

    public static synchronized MySingleton getSingleton() {
        if (singleton == null) {
            singleton = new MySingleton();
        }
        return singleton;
    }
}
于 2013-02-15T08:34:39.380 回答