Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.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 双重检查锁定,NetBeans让我困惑?_Java_Synchronization_Double Checked Locking - Fatal编程技术网

Java 双重检查锁定,NetBeans让我困惑?

Java 双重检查锁定,NetBeans让我困惑?,java,synchronization,double-checked-locking,Java,Synchronization,Double Checked Locking,我有一个关于双重检查锁定的问题。 考虑这个例子: public class Singleton { private static volatile Singleton instance = null; public static Singleton getInstance() { if(instance == null) { synchronized(Singleton.class) { if(in

我有一个关于双重检查锁定的问题。 考虑这个例子:

public class Singleton {

     private static volatile Singleton instance = null;

     public static Singleton getInstance() {
        if(instance  == null) {
            synchronized(Singleton.class) {
                if(instance  == null) {
                    instance  = new Singleton();
                }
            }
        }
        return instance ;
    }
}
据我所知,上面的代码是创建Singleton类的正确方法

但是,NetBeans希望我删除外部if语句,因此它看起来是这样的:

public class Singleton {

     private static volatile Singleton instance = null;

     public static Singleton getInstance() {
        synchronized(Singleton.class) {
            if(instance  == null) {
                instance  = new Singleton();
            }
        }
        return instance ;
    }
}

这两个代码段之间的唯一区别在于,在第二个示例中,代码将始终进入同步块,而在第一个示例中不会。为什么我要监听NetBeans并删除外部if语句?最好避免锁死

在这种情况下不要听NetBeans。您的第一个代码示例是正确的。

NetBeans的自动提示系统显然没有意识到可以像您所做的那样,使用
volatile
正确执行双重检查锁定,因此建议改为完全锁定。安全总比后悔好。但在这种情况下,您是对的,而不是NetBeans。

大多数情况下,将使用singleton,而且创建成本不高,所以请简化:

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    public static Singleton getInstance() {
        return INSTANCE;
    }
    ...
}
如果确实需要延迟实例化,请使用静态内部类:

public class Singleton {
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
    ...

    private static class Holder {
        private static final Singleton INSTANCE = new Singleton();
    }
}

顺便说一句:我只需要使用
enumsingleton{INSTANCE}
它要简单得多事实上,NetBeans是对的。。。如果代码是在5.0之前的JVM上运行的。@Stephen C,但即使是1.5也在一段时间前完成了它的使用寿命。甚至Sun 1.4实现也支持1.5 JMM。除非你的目标是JavaMe,否则这是不对的。在JVM版本之间更改内存模型语义是一件痛苦的事情,当然你应该瞄准最坏的情况。幸运的是1.4现在基本上不存在了(我希望如此!)。事实上,NetBeans是正确的。。。如果代码在5.0之前的JVM上运行。参考维基百科文章。NetBeans应该参考源代码级别。如果源代码级别为1.4或更低,那么NetBeans当然是正确的。但是如果源代码级别是1.5/1.6/1.7,那么NetBeans是不对的。事实上,我认为这将是实际执行代码的平台级别。