8

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

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

据我了解,上面的代码是制作单例类的正确方法。

但是,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 语句?最好避免锁定。

4

3 回答 3

3

NetBeans 的自动提示系统显然不知道可以volatile像您所做的那样正确地进行双重检查锁定,因此它建议改为完全锁定。安全总比后悔好。但在这种情况下你是对的,而不是 NetBeans。

于 2011-12-07T09:37:09.483 回答
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();
    }
}
于 2011-12-07T09:40:16.937 回答
0

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

于 2011-12-07T09:36:05.270 回答