public class DCL {
private static DCL staticDcl;
private final DCL finalDcl;
private DCL(){
//other init operation
//the action must be last.
finalDcl = this;
}
public static DCL getDCL() {
if (staticDcl == null) {
synchronized(DCL.class) {
if (staticDcl == null) {
staticDcl = new DCL();
}
}
}
return staticDcl.finalDcl;
}
}上面的代码可以在多线程环境下正常运行吗?
我想使用关键字final来实现dcl不挥发。
发布于 2021-02-01 18:13:00
您可能会遇到问题,请参阅Why is volatile used in double checked locking?
我建议不要使用这种模式,而是使用static holder pattern (SHP),它保证了您尝试重现的所有机制。使用SHP,您甚至不必考虑volatile,因为JVM直接为您处理它。
public class DCL {
private DCL(){
//other init operation
}
public static DCL getDCL() {
return Holder.INSTANCE;
}
private static final class Holder {
private static final DCL INSTANCE = new DCL();
}
}还要注意,private final DCL finalDcl;是多余的,因为您可以直接返回实例,不需要创建一个等于this的新字段。
此模式的好处是,只有在第一次引用INSTANCE时,即调用getDCL()时,才会实例化它。这是由于lazy class loading的性质造成的。
发布于 2021-02-02 03:14:16
是的,没有volatile,it is potentially broken,你可以阅读我的另一个答案来获得解释。
你有staticDcl和finalDcl,这很奇怪。如果您希望通过DCL提供单例,则不需要两个都需要。你可以阅读this问题的开头,了解如何实现这一点。它还讨论了如何在没有volatile的情况下实现双重检查锁定安全,但仍然使用了一些特殊的语义,如release/acquire。
https://stackoverflow.com/questions/65990662
复制相似问题