2016-05-18 42 views
0

起初我有我的单身类这样这是在Java中初始化Singleton类的错误方法吗?

private static MqttHandler instance = new MqttHandler(); 
private MqttHandler(){}; 
public MqttHandler getInstance(){ 
    return instance; 
} 

现在一个电话,它正在按照预期,但在另一个,好像它是创造许多情况下,因为每当我试图登录的东西,它没有日志多次。我不知道为什么。 我第二次尝试使用这个

private MqttHandler instance; 
    private MqttHandler(){}; 
    public MqttHandler getInstance(){ 
     if(instance==null) instance == new MqttHandler(); 
     return instance; 
    } 

似乎是工作,至少现在,不知道它去后崩溃,这是否意味着,在我的第一个方法,每当我返回的实例,它正在呼叫

new MqttHandler(); 

因此会一直创建新的实例吗?为什么它会在一台设备上正常工作,然后完全拒绝另一台设备?

+0

第二个例子是非常不鼓励,因为它不是线程安全的。第一次尝试应该可以正常工作。 – Turing85

+0

你如何使用第一个?我看到你有一个私有构造函数,意味着其他类不能实例化它,但是'getInstance'方法是一个实例方法。此外,这里'if(instance == null)instance == new MqttHandler();'你在做什么?如果它为空,并且你试图将一个新实例存储到'instance'变量,那么执行'instance = new MqttHandler();'。 –

回答

0

这是如何实现一个简单的singleton

// It must be static and final to prevent later modification 
private static final MqttHandler INSTANCE = new MqttHandler(); 
// The constructor must be private to prevent external instantiation 
private MqttHandler(){}; 
// The public static method allowing to get the instance 
public static MqttHandler getInstance() { 
    return INSTANCE; 
} 

你的第二个方法只能在单线程应用工作,因为如果你在同一时间与多个并发线程调用getInstance,它会创建的几个实例你的对象,这样你的单身人士的合同将被打破。所以,如果你需要适当地懒惰创建你的单身人士,这里是如何继续:

// The constructor must be private to prevent external instantiation 
private MqttHandler(){}; 
// The public static method allowing to get the instance 
public static MqttHandler getInstance() { 
    return MqttHandlerHolder.INSTANCE; 
} 
    /** 
* The static inner class responsible for creating your instance only on demand, 
* because the static fields of a class are only initialized when the class 
* is explicitly called, this rule is also applicable to inner static class 
* So here INSTANCE will be created only when MqttHandlerHolder.INSTANCE will be called 
*/ 
private static class MqttHandlerHolder { 
    private static final MqttHandler INSTANCE = new MqttHandler(); 
} 
+0

一些额外的位:这是懒惰的初始化,因为类的静态字段第一次被初始化,类在执行时被使用。 – Turing85

+0

@ Turing85没错,我在这里和我的回复中添加了它http://stackoverflow.com/a/37305099/1997376 –

0

两者应该具有相同的效果。当然,后者的好处是该对象不会在实际需要之前创建,但请注意,由于并发调用getInstance,该对象可能会多次创建。另外,您需要getInstance中的“静态”声明(否则您将不得不创建一个实例来获取单例)。

+0

第二个示例(又称。懒惰初始化)不是线程安全的。执行'getInstance()'的两个线程可以将'instance'看作'null',从而初始化一个新的对象,打破单例模式。 – Turing85

相关问题