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

时间:2011-12-07 09:33:24

标签: 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(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语句?应该更好地避免锁定。

3 个答案:

答案 0 :(得分:3)

NetBeans的自动提示系统显然不知道可以正确地使用volatile进行双重检查锁定,因为它建议完全锁定。比抱歉更安全。但在这种情况下你是对的,而不是NetBeans。

答案 1 :(得分:3)

大多数情况下,将使用单身人士,并且创建成本不高,所以只需简单说明:

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();
    }
}

答案 2 :(得分:0)

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