Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这种单例设计模式正确吗?_Java_Design Patterns_Singleton - Fatal编程技术网

Java 这种单例设计模式正确吗?

Java 这种单例设计模式正确吗?,java,design-patterns,singleton,Java,Design Patterns,Singleton,这种单例设计模式正确吗?我的意思是,当对象是静态的并且方法是同步的时,需要检查对象是否为null public class MySingleton { int val = 10; private static final MySingleton singleton = new MySingleton(); private MySingleton() { } public static synchronized MySingleton getSingleton

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

public class MySingleton {

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

    private MySingleton() { }

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

您不需要使方法同步。在静态初始值设定项中初始化变量就足够了。另外,您的
val
变量几乎肯定是私有的

当您不需要同步方法和静态初始值设定项时,通常使用双重检查锁定模式(带有空性检查)。(在我看来,它几乎在所有情况下都是不必要的复杂和脆弱。)

另一种选择是使用枚举:

public enum MySingleton {
    INSTANCE;

    private int val = 10;

    // Presumably something to use val
}

使用枚举可以强制实现单例性,甚至在序列化时也可以做到这一点。这也是一种非常简单的方法,没有实际的代码:)另一方面,我从来没有觉得它完全正确…

最好的模式是Joshua Bloch在他的书《有效Java,使用枚举:

public enum MySingleton {
    INSTANCE;

    public void doSomething() {

    }
}
引用该书:


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

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

public class MySingleton {

    private static MySingleton singleton = null

    private MySingleton() { }

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

值得注意的是,除非您有其他静态方法,您希望能够在不创建实例的情况下运行这些方法,否则只使用静态初始值设定项是可以的——在第一次使用类之前,静态初始值设定项仍然是惰性的。您好,overmeulen。您的答案贡献不大,因为您没有说明为什么此模式是“最佳”模式“。为了改进您的答案,您可以写一点关于它的优点和缺点以及为什么它比OPs方法更可取。关于synchronized关键字,我还有一个疑问,静态变量或方法是线程安全的吗?”?我在谷歌上搜索了一下,第一印象是它们不是,这就是我使用synchronized的原因。@Praveen Kumar,通过调用getSingleton()方法,创建了singleton对象。因为它已经创建了,所以不需要同步。