• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Tim Cooke
  • Bear Bibeault
  • paul wheaton
Saloon Keepers:
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Mikalai Zaikin
  • Piet Souris
Bartenders:

Synchronization for Singleton

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why is it suggested that the getInstance() method in a Singleton class sould be synchonized even if the Singleton class object is declared static
 
Bartender
Posts: 2292
3
Eclipse IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Howdy, Tulika. Welcome to JavaRanch!

Please take a look here. I think it might be helpful!
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tulika Shil wrote:Why is it suggested that the getInstance() method in a Singleton class sould be synchonized even if the Singleton class object is declared static



"Even if the variable is declared static" has nothing to do with it. (And note, it's the variable that's static, not the object. Objects do not have the property of being static or non-static.) Whether a variable is static or not, if multiple threads can access it concurrently and one or more of those threads could be writing it, then all access to it has to be synchronized (or, in some cases, just declaring it volatile is enough, but not in this case).

However, syncing is only necessary when doing lazy loading, and lazy loading is never the right approach, so if you do your singleton right, you don't need to sync the getInstance() method.



In the second example, we need syncing because otherwise multiple threads could all see true for "instance == null" and then each would create its own instance.
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This pattern by William Pugh is thread-safe and lazy. Hence it is the best way and considered standard practice. http://en.wikipedia.org/wiki/Singleton_pattern


 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Thomas Punihaole wrote:This pattern by William Pugh is thread-safe and lazy.



It also adds an extra level of complexity, and lazy loading is never necessary or even beneficial.

Hence it is the best way and considered standard practice.



No, it's definitely not the best, and while it's fairly common, I certainly wouldn't call it "standard practice."
 
Roberto Perillo
Bartender
Posts: 2292
3
Eclipse IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:No, it's definitely not the best, and while it's fairly common, I certainly wouldn't call it "standard practice."



Agreed. I avoid using Singletons, but if I had to, I'd go for the first approach provided by Jeff in his first post.
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roberto Perillo wrote:Agreed. I avoid using Singletons, but if I had to, I'd go for the first approach provided by Jeff in his first post.


Personally, I quite like:but yes, for a class, I've only ever found one case for using Pugh's "initialize-on-demand class holder idiom". It's too much of a mouthful anyway.

Winston
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:However, syncing is only necessary when doing lazy loading, and lazy loading is never the right approach, ...


Can you explain why lazy loading is never the right approach?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesper de Jong wrote:

Jeff Verdegan wrote:However, syncing is only necessary when doing lazy loading, and lazy loading is never the right approach, ...


Can you explain why lazy loading is never the right approach?



Let me state up front that by "lazy loading" I assume we're talking about "lazy instantiation" of the Singleton instance. If somebody's talking about something else, please let me know.

My thinking goes like this:

What's the point of lazy instantiation? To avoid incurring the cost of constructing the singleton unnecessarily.

However, the usual use of a Singleton is


Lazy instantiation buys us nothing here. If we're going to use it, we have to construct it. Since Java loads classes on demand, our Singleton class won't be loaded until we use it, so we won't incur the cost of eagerly instantiating the object until we're on the verge of using it.

So when might lazy instantiation be useful? The only case would be if we're using the class but not using the instance, or not using it until some time later:


So we might decide that we don't want to incur the cost of construction of the instance upon loading the class when we're just using the static methods. Defer that cost until we need it, and don't incur it at all, if not needed. So here we would use lazy instantiation, so that we can use the class without incurring the overhead of constructing the instance.

But if this is your use case, you almost certainly have a design flaw. What would be the case where you would actively use a bunch of static methods in your singleton, but never instantiate it, or instantiate it somewhere distant from the use of the static methods? That sounds like a serious failure of separation of responsibility.

Add to that the fact that in almost every case, instantiation is not a heavyweight or expensive operation, and there's just no real practical benefit.

Now, I can see one specific use case where it could be valuable. All of the above is predicated on the idea that a class is not loaded until it's referenced. That is, the early part of your program won't suffer from incurring the cost of instantiating a singleton that's not used until later. However, as I understand it, neither the JLS nor the JVM spec actually requires that classes be loaded on demand; it just so happens that that's what every major JSE VM does. However, if some particular JVM that you're targeting is observed to load all its classes on startup, AND if your singleton is expensive to construct, AND if it's not used until later in the program or potentially not at all, THEN, and only then, as far as I can tell, might lazy instantiation be useful.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:However, as I understand it, neither the JLS nor the JVM spec actually requires that classes be loaded on demand; it just so happens that that's what every major JSE VM does.


Actually, according to Josh Bloch, JLS 12.4.1 does make that guarantee; but it's quite a big para and I haven't bothered to check.

I agree with everything else you say, but I have a question: Does simply declaring a variable, eg:
private Singleton s;
count as a 'reference'? Because if so, you could have the case of a class that needs to declare it without actually using it.

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:
I agree with everything else you say, but I have a question: Does simply declaring a variable, eg:
private Singleton s;
count as a 'reference'? Because if so, you could have the case of a class that needs to declare it without actually using it.

Winston



I don't think simply having that declaration causes the class to be loaded, nor, for that matter, does having, say, a call to s.foo() inside an if block that never gets executed. But a) it's easy enough to test, and b) I still don't see a real-world situation arising where that happens AND the singleton is expensive to construct AND the use of the instance is so distant or never occurs at all such that instantiating it early actually causes a problem.
 
Sheriff
Posts: 22755
130
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The relevant part:

http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html wrote:A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the reference to the field is not a compile-time constant (ยง15.28). References to compile-time constants must be resolved at compile time to a copy of the compile-time constant value, so uses of such a field never cause initialization.

  • Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.

     
    Roberto Perillo
    Bartender
    Posts: 2292
    3
    Eclipse IDE Spring Java
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    In 2010, some guys of the magazine where I publish articles and work as tech member interviewed the GoF. When they were asked what were the patterns that they would take off the book if it was today, the first pattern that they mentioned: Singleton.
     
    Jeff Verdegan
    Bartender
    Posts: 6109
    6
    Android IntelliJ IDE Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Rob Spoor wrote:The relevant part:



    Thanks Rob. I was too lazy too look, and didn't expect it to be spelled out that directly.
     
    Bras cause cancer. And tiny ads:
    Low Tech Laboratory
    https://www.kickstarter.com/projects/paulwheaton/low-tech-0
    reply
      Bookmark Topic Watch Topic
    • New Topic