【问题标题】:Singleton in java not create instancejava中的单例不创建实例
【发布时间】:2014-06-10 00:52:23
【问题描述】:

我正在尝试在我的 java servlet 中创建一个单例实例。但是我有一些我找不到的问题。

我用一种方法执行这个:

 RegisterHandler reg = RegisterHandler.getInstance();

在 registerHandler 中我有 getInstance 方法:

private static RegisterHandler instancia ;  

public static RegisterHandler getInstance() {  
    if(instancia==null){ //SI ES NULL
       instancia = new RegisterHandler(); //LO INSTANCIAMOS
    }
    return instancia;  
} 

我认为如果它不存在或现有实例,它应该返回一个新实例,但是当我第一次尝试执行它时,它进入 instancia==null 并崩溃。没有给出错误。

有什么想法吗?

我添加了我的构造函数:

private RegisterHandler() { 
    try {
        this.publisher = new AMQEventPublisher("failover:tcp://127.0.0.1:9009");
    } catch (NormalException e) {
        log.error("Error",e);
    }
}

【问题讨论】:

  • RegisterHandler 构造函数有什么作用?
  • RegisterHandler 的构造函数里有什么?是吞咽异常吗?
  • 您没有显示会导致程序崩溃的代码。如果它抛出异常,则它在您未显示的代码中。你能告诉我们异常、堆栈跟踪以及异常是在哪一行被抛出的吗?
  • 它没有给出例外。这就是我不知道它为什么失败的问题。但是 new Regist... 行没有执行,并且程序不会从那一点继续

标签: java singleton


【解决方案1】:

声明instancia volatile。 另外为了避免RegisterHandler的可能重复使用双重锁定:

private static volatile RegisterHandler instancia;
private static final Object instanciaLockObject = new Object();

public static RegisterHandler getInstance() {  
    if(instancia==null){ //SI ES NULL
       synchronized(instanciaLockObject) {
            if(instancia==null){
               instancia = new RegisterHandler(); //LO INSTANCIAMOS
            }
       }
    }
    return instancia;  
} 

这种模式称为双重检查锁定:http://en.wikipedia.org/wiki/Double-checked_locking

【讨论】:

  • 也许你可以添加什么时候使用它而不是一个实例的枚举。
  • 同时创建一个私有构造函数只是为了避免外部程序创建一个RegisterHandler的实例
  • 双锁也有漏洞,使用SingletonHolder或者枚举模式
  • 我知道 Java (5+) 中的双重检查锁定没有漏洞。如果您声明实例 volatile,那么它从 Java 5 开始就可以正常工作(在 Java 4 中存在问题,但是来吧,它很快就是 Java 8)。至于具有单个实例的 Enum - 将不再进行延迟初始化。
  • 我想你在 RegisterHandler 构造函数的某个地方有空指针异常。不在您发布的代码中。
【解决方案2】:

为了确定起见,我还会将 instancia 设置为 null 开始。可能是我偏执,但我相信代码中的“比抱歉更安全”的规则。

【讨论】:

  • 但是第一次进入时,instancia 为空。我进入那个 if 条件。
  • instancia 默认为空。
  • 我只是在风格上设置为 null,因为我来自 C 背景,但在可读性方面并没有什么坏处:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多