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是不对的。事实上,我认为这将是实际执行代码的平台级别。