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,下面的片段是直截了当的 public MyClass getInstance() { if(uniqueInstance == null) { uniqueInstance = new MyClass(); } return uniqueInstance; } 下面这个是做什么的 public MyClass getInstance() { if(uniqueInstance == null) { synchronized(MyC

下面的片段是直截了当的

public MyClass getInstance() {
    if(uniqueInstance == null) {
        uniqueInstance = new MyClass();
    }
    return uniqueInstance;
}
下面这个是做什么的

public MyClass getInstance() {
    if(uniqueInstance == null) {
        synchronized(MyClass.class) {
            uniqueInstance = new MyClass();
        }
    }
    return uniqueInstance;
}

这是线程安全的一点保险

摘自javaworld文章:

同步方法可以保证 无法调用该方法 打断了


其主要思想是,如果您没有同步块,那么两个线程可能会调用getInstance并重新初始化对象,从而可能丢失任何状态数据(如果您甚至应该在单例中有状态数据)

这是线程安全的一点保障

摘自javaworld文章:

同步方法可以保证 无法调用该方法 打断了


其主要思想是,如果没有同步块,则两个线程可以调用getInstance并重新初始化对象,从而可能丢失任何状态数据(如果您甚至应该在单实例中包含状态数据)试图使其线程安全以防止至少两个线程同时进入
if
块而导致的争用状态是一种错误的尝试

一种更安全的方法是添加一个额外的nullcheck,也称为


但是,我通常更喜欢单线程。

为了防止至少两个线程同时进入
if
块而导致的争用情况,使其线程安全是一种拙劣的尝试

一种更安全的方法是添加一个额外的nullcheck,也称为


但是,我通常更喜欢单例。

第二种方法做同样的事情,除了:如果使用第一种方法,如果创建一个新的MyClass需要一些时间,那么在这段时间内,其他人也会调用MyClass.getInstance()?您可能最终得到两个实例。第二个版本锁定实例化行,因此如果另一个类同时尝试调用,它将等待第一个类完成。

第二个版本执行相同的操作,除了:如果使用第一个版本,如果创建一个新的MyClass需要一些时间,会发生什么情况,并且在此期间,其他人也调用MyClass.getInstance()?您可能最终得到两个实例。第二个版本锁定实例化行,因此如果另一个类同时尝试调用,它将等待第一个类完成。

IMHO您应该首先从最简单的选项开始。最简单的单例是一个带有一个条目的枚举。考虑到类是惰性加载的,这仍然会给您惰性加载,除非您直接引用该类,而且这种情况不会轻易发生

enum Singleton {
   INSTANCE;
}
为了避免意外加载,可以使用内部类

class Singleton {
    static class SingeltonHolder {
        static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
注;这两种解决方案都不需要同步,因为它们使用了类加载是线程安全的这一事实


简言之;有些情况下需要锁定,但不要让它变得比需要的更复杂。

我想你应该先从最简单的选项开始。最简单的单例是一个带有一个条目的枚举。考虑到类是惰性加载的,这仍然会给您惰性加载,除非您直接引用该类,而且这种情况不会轻易发生

enum Singleton {
   INSTANCE;
}
为了避免意外加载,可以使用内部类

class Singleton {
    static class SingeltonHolder {
        static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
注;这两种解决方案都不需要同步,因为它们使用了类加载是线程安全的这一事实

简言之;有些情况下需要锁定,但不要让它变得比需要的更复杂。

“更安全一点”。。。我不太确定:@Karl:所以有点。维基百科的链接文章也解释了这一点。“更安全一点”。。。我不太确定:@Karl:所以有点。维基百科的链接文章也解释了这一点。