• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Synchronization for Singleton

 
Tulika Shil
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • 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
 
Roberto Perillo
Bartender
Posts: 2271
3
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Howdy, Tulika. Welcome to JavaRanch!

Please take a look here. I think it might be helpful!
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • 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.
 
Thomas Punihaole
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • 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
  • 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: 2271
3
Eclipse IDE Java Spring
  • Mark post as helpful
  • send pies
  • 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.
 
Winston Gutkowski
Bartender
Pie
Posts: 10277
60
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • 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
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15219
36
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • 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
  • 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
Pie
Posts: 10277
60
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • 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
  • 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.
 
Rob Spoor
Sheriff
Pie
Posts: 20514
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • 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: 2271
    3
    Eclipse IDE Java Spring
    • Likes 1
    • Mark post as helpful
    • send pies
    • 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
    • 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.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic