首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在没有关键工作挥发的情况下实现DCL?

如何在没有关键工作挥发的情况下实现DCL?
EN

Stack Overflow用户
提问于 2021-02-01 18:02:31
回答 2查看 69关注 0票数 2
代码语言:javascript
复制
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不挥发。

EN

回答 2

Stack Overflow用户

发布于 2021-02-01 18:13:00

您可能会遇到问题,请参阅Why is volatile used in double checked locking?

我建议不要使用这种模式,而是使用static holder pattern (SHP),它保证了您尝试重现的所有机制。使用SHP,您甚至不必考虑volatile,因为JVM直接为您处理它。

代码语言:javascript
复制
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的性质造成的。

票数 1
EN

Stack Overflow用户

发布于 2021-02-02 03:14:16

是的,没有volatileit is potentially broken,你可以阅读我的另一个答案来获得解释。

你有staticDclfinalDcl,这很奇怪。如果您希望通过DCL提供单例,则不需要两个都需要。你可以阅读this问题的开头,了解如何实现这一点。它还讨论了如何在没有volatile的情况下实现双重检查锁定安全,但仍然使用了一些特殊的语义,如release/acquire

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65990662

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档