13 Replies Latest reply: Mar 6, 2013 7:22 AM by gimbal2 RSS

    Double Check Locking

    761757
      Hi ,

      I have picked the below code snippet directly from Wikipedia and did some searches on the problem of DCL. Am pasting the code just for convenience .
      public class Something {
              private Something() {
              }
       
              private static class LazyHolder {
                      private static final Something INSTANCE = new Something();
              }
       
              public static Something getInstance() {
                      return LazyHolder.INSTANCE;
              }
      }
      Now this code follow 'intitalization-on-demand' structure . Now as per my understanding of JVM Spec , any java object initialization is serial or thread safe. So the time when static object is getting created by a thread others would be waiting for its completion which would avoid the problem of in-complete objects being used by other threads.

      Now if this hold good ,whats wrong with the below implementation , wont it stand good in multi-threaded system . Please correct me if my understanding was wrong.
      public class Something {
              private Something() {
      
                     //do your stuff here
              }
       
             private static final Something s=new Something();
      
              public static Something getInstance()
                {
                     return s;
                }
      }
      Thanks
        • 1. Re: Double Check Locking
          Kayaman
          I'm not going into the details of DCL and why a particular implementation doesn't work. Yours doesn't do lazy loading, so it's a bad example.

          But if you're going to actually use DCL, you're wasting your time. Even if the current JVM implementation makes it work, it has never been a real performance issue. Uncontended synchronization is fast.
          • 2. Re: Double Check Locking
            gimbal2
            Kayaman wrote:
            Uncontended synchronization is fast.
            Short lived object garbage collection is also really fast. Caching instances is also something from the past IMO. Unless you really -need- a singleton.
            • 3. Re: Double Check Locking
              Tolls
              In practical terms, unless your singleton holds some other data that means the class could be loaded, but not the 'instance' variable, then both will result in the 'instance' being instantiated on the first call to getInstance().

              When I had written singletons (and I can't remember the last time I did that) I never used the lazy version.
              There was no point.
              • 4. Re: Double Check Locking
                761757
                Hi ,

                I totally agree with you as I have been using the normal synchronized method and for sure never faced any bottle neck . But this was something which came up during a discussion between me and my colleagues .

                Yes I understand its not a lazy loading , but as per my understanding it still holds good for solving DCL problem . Am not exactly sure why is this a bad example as per DCL problem?

                I might not end up implementing DCL and might always want to go with normal synchronized method ( untill I really end up in bottleneck) , but I wanted to keep my concepts clean that why this approach is termed as bad for DCL problem , when ( as per my understanding) it satisfies the java language specifications.

                Thanks
                • 5. Re: Double Check Locking
                  Tolls
                  If you are writing a singleton, then the second example you give is the way to do it 99% of the time (probably more).
                  Actually, I take that back. There's the enum version as well, but I've never really seen the point of that one over the above, though I will freely admit that is likely just personal preference.

                  The synchronised method hasn't been advisable for as long as I can remember...
                  • 6. Re: Double Check Locking
                    761757
                    Thanks Tolls for the explanation. Yes synchronized might not be the best way to do it but the application I work on has small number of users so never end up in any performance bottlenecks .

                    But if this is not the best method , then the other 2 better ways to do it , which I know , would be either using volatile or lazy loading . Which one do you suggest?

                    Thanks
                    • 7. Re: Double Check Locking
                      761757
                      Hi,

                      Sorry I didn't understood well when you said 'Short lived object garbage collection is also really fast.' . Can you throw some light on this please.

                      Thanks
                      • 8. Re: Double Check Locking
                        Kayaman
                        user10079576 wrote:
                        Sorry I didn't understood well when you said 'Short lived object garbage collection is also really fast.' . Can you throw some light on this please.
                        Years ago there was this whole performance thing. People would use DCL because they thought it was "faster", when in fact it was "broken". Object allocation was feared as well, even though it was often baseless.

                        These days there are still people who don't know that progress has happened, so they're trying to use some old tricks for performance reasons. Which is completely asinine.
                        • 9. Re: Double Check Locking
                          Tolls
                          user10079576 wrote:
                          Thanks Tolls for the explanation. Yes synchronized might not be the best way to do it but the application I work on has small number of users so never end up in any performance bottlenecks .

                          But if this is not the best method , then the other 2 better ways to do it , which I know , would be either using volatile or lazy loading . Which one do you suggest?

                          Thanks
                          Synchronising isn't guaranteed to work in the usual singleton case.
                          Nothing to do with performance, but it may result in more than one "singleton" being created.

                          If writing a singleton use the second example above (which is not lazy loading, that's the first one).
                          Unless your singleton has more than one non-private static method, or some public static variables...neither case being terribly common in my experience.
                          • 10. Re: Double Check Locking
                            Kayaman
                            Tolls wrote:
                            Synchronising isn't guaranteed to work in the usual singleton case.
                            What do you mean? It is guaranteed to work in the usual singleton case, where the getInstance() method is synchronized.
                            public class Singleton {
                                Singleton instance;
                                public static synchronized Singleton getInstance() {
                                    if(instance == null) instance = new Singleton();
                                    return instance;
                                }
                            }
                            A non-lazy loading singleton is trivial case.
                            Nothing to do with performance, but it may result in more than one "singleton" being created.
                            DCL is an attempt to get rid of the synchronization for "performance" purposes, and at least in older JVMs could result in multiple instances being created.
                            • 11. Re: Double Check Locking
                              Tolls
                              Kayaman wrote:
                              Tolls wrote:
                              Synchronising isn't guaranteed to work in the usual singleton case.
                              What do you mean? It is guaranteed to work in the usual singleton case, where the getInstance() method is synchronized.
                              public class Singleton {
                              Singleton instance;
                              public static synchronized Singleton getInstance() {
                              if(instance == null) instance = new Singleton();
                              return instance;
                              }
                              }
                              A non-lazy loading singleton is trivial case.
                              Nothing to do with performance, but it may result in more than one "singleton" being created.
                              DCL is an attempt to get rid of the synchronization for "performance" purposes, and at least in older JVMs could result in multiple instances being created.
                              Damn...I knew I should have double checked what I was blathering on about.
                              It was, as you say, the DCL method that I was thinking of.

                              You can tell it's been an awfully long time since I even bothered to look at this.
                              • 12. Re: Double Check Locking
                                Kayaman
                                Tolls wrote:
                                Damn...I knew I should have double checked what I was blathering on about.
                                It was, as you say, the DCL method that I was thinking of.

                                You can tell it's been an awfully long time since I even bothered to look at this.
                                You almost got me thinking I was talking about the wrong thing as well :)
                                This has indeed been a non-issue for a long time...
                                • 13. Re: Double Check Locking
                                  gimbal2
                                  Kayaman wrote:
                                  This has indeed been a non-issue for a long time...
                                  Unfortunately there is nothing as permanent as a temporary solution. The internet remembers, FOREVER!