我之前已经实现了 Singleton 类,它对 Singleton 实例使用双重锁定机制,但我们收到了 SonarLint 错误 在双重锁定上不应使用双重检查锁定 (squid:S2168)
代码。
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
为了解决这个问题,我想到在 Singleton 对象引用之前放置 volatile
关键字,如下所示。
private static volatile Singleton singleton;
但是在将此字段设置为 volatile 之后,SonarLint 会给出错误非原始字段不应为“ volatile ”(squid:S3077)
这是否意味着现在将对象引用设置为 volatile 不是一个好习惯,因为大多数可用的单例示例都像提到的代码示例一样?
最佳答案
关于你的尝试, Sonar 确实给出了 volatile
字段as workaround但看起来根据新问题,当你使用它时,它本身就矛盾了......
不明显:)
but we got an SonarLint error of Double-checked locking should not be used (squid:S2168) on double locking code.
我会删除确实容易出错且冗长的双重检查锁定。
热切初始化是线程安全的,并且在大多数情况下都很好:
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return singleton;
}
}
持有者类的惰性方式也是一种替代方法(虽然我通常会避免,因为惰性通常不是必需的):
public class Singleton {
private static class SingletonHolder{
static final Singleton singleton = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.singleton;
}
}
关于java - 在更新的 4.1 版本中对 Singleton 类使用双重锁定时,Sonarlint 在 volatile 对象引用上给出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57289350/