Is DCL still broken?

前端 未结 2 1785
清歌不尽
清歌不尽 2021-01-14 21:35

As far as I understand with old JMM the DCL (Double checked Locking) trick to implement lazy singletone was broken, but i tought that it was fixed with new JMM and volatile

相关标签:
2条回答
  • 2021-01-14 21:53

    It was fixed in Java 5.

    However these days the "correct" (i.e. the simplest) way is to use an enum for lazy initialization.

    public enum Singleton {
        INSTANCE;
    
        // No need for a getInstance() method
        //public static Singleton getInstance() {
        //    return INSTANCE;
        //}
        // Add methods to your liking
    }
    
    0 讨论(0)
  • 2021-01-14 22:19

    Here and there i read that it is fixed then i discover this... Can someone just say finally is it broken or not?

    It depends on what you mean by "it".

    If you are asking if you can do DCL with a volatile then the answer is Yes, post Java 5. (The original semantics of volatile were not well defined, which meant that using a volatile wasn't a fix, pre Java 5.)

    If you are asking if you can do DCL without a volatile then the answer is No. The Java 5 memory model changes don't "fix" the original Java implementation of DCL with a non-volatile instance variable.

    If you are asking if it is still a good idea to use DCL for lazy initialized singletons, then the answer is No. (In my opinion):

    • There are better ways to implement a lazily initialized singleton. Using an enum is one of them.

    • Since the DCL idiom is still error prone and not well understood1, it is better to avoid it.

    • Synchronization performance improvements have largely removed the need for DCL.


    Enum and static init will initialize the singletone on class load (correct me if i'm mistaken).

    I think that you are mistaken. Class initialization is also lazy. It doesn't happen at class load time unless you force it; e.g. by using the 3-arg overload of Class.forName. JLS 12.4.1 sets out the rules that determine when it occurs.

    The upshot is that you can ensure that initialization of an enum-based singleton happens lazily, and it will definitely be done safely.

    As an aside, a hard requirement for lazy initialization is suggestive to me of a problem in your application design. At the very least, it introduces a point of fragility ... no matter how the lazy initialization is implemented.


    1 - If an "average Joe programmer" doesn't understand the intricacies of DCL, then it is a bad idea to use DCL in code that he might need to maintain. The fact that you are smarter than the average Joe programmer is moot.

    0 讨论(0)
提交回复
热议问题