aspose file tools*
The moose likes Threads and Synchronization and the fly likes Question regarding Singleton pattern Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Question regarding Singleton pattern" Watch "Question regarding Singleton pattern" New topic
Author

Question regarding Singleton pattern

B.Sathish
Ranch Hand

Joined: Aug 18, 2005
Posts: 372
In the double-checked locking implementation mentioned in Head First Design Patterns, I don't understand why the static variable holding the Singleton instance needs to be volatile. I think it would work fine, even if it is not volatile.

Can some one explain why this code needs the variable to be volatile? Also, I am not able to clearly understand why this code would work only in Java 5 and not previous versions

Here is the code from the book for the double-checked locking implementation of the Singleton pattern :

public Class Singleton
{
private static volatile Singleton uniqueInstance;

private Singleton(){}

public static Singleton getInstance()
{
if (uniqueInstance == null)
{
synchronized (Singleton.class)
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}

Why should uniqueInstance be volatile? What will happen if it's non-volatile?
and Why would this work only in Java 5?
Harshil Mehta
Ranch Hand

Joined: Mar 17, 2005
Posts: 64
Hi Satish,

  • Each thread can have it's own copy of primitive as well reference identifiers which can be not in sync with other thread's set. Imagine following situation.


  • There are three threads A,B and C which are having reference of class Singleton. In their regular course of running, say thread A makes derefers Singleton reference, so in thread A's memory set, reference of class is null and as it's singleton class, same reference is referred by thread B and C. I know it's not practical, but we can't force JVM not doing this.

    Making reference uniqueInstance volatile will force JVM to update each individual thread's memory set to be in sync with eachother. And so above situation can be prevented. We can prevent using any null reference and inviting NullPointerException by checking its instance for NOT NULL condition before doing any thing critical.

  • Nothing will happen in regular java programs, this is specific to some critical situation only. I have not seen HFJava book so can't comment what will happen without seeing whole program.

  • I was able to compile and run the program in JDK1.4.




  • Ranchers, please correct me if i am wrong.

    Regards,
    Harshil
    Ilja Preuss
    author
    Sheriff

    Joined: Jul 11, 2001
    Posts: 14112
    As this is very specific to multi-threading, I'm moving to Threads and Synchronization...


    The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
    Jeff Albertson
    Ranch Hand

    Joined: Sep 16, 2005
    Posts: 1780
    Too complicated! 99%+ of the time, the following is sufficient, and nothing
    could be simpler:
    The less than 1% of the time this approach is bad is when Singleton has
    other static methods that should be callable, first, without causing the
    instance to be loaded.


    There is no emoticon for what I am feeling!
    Paul Clapham
    Bartender

    Joined: Oct 14, 2005
    Posts: 18991
        
        8

    The original code posted is an example of the "double-checked locking" problem. Google for that to find out more about it (the explanations you find will be far better than mine anyway). Maybe the problems it exposes in the Java memory model have been fixed in Java 5, but I don't know that for sure. Even if they have, I would still use the simple reliable version that Jeff posted.
    Jignesh Patel
    Ranch Hand

    Joined: Nov 03, 2001
    Posts: 626

    may be this help you.
    http://cephas.net/blog/2003/02/17/using_the_volatile_keyword_in_java.html
    B.Sathish
    Ranch Hand

    Joined: Aug 18, 2005
    Posts: 372
    Thanks for the reply Jignesh. I think I understand now why that variable needs to be volatile. Looks like I have really understood volatile variables only now when reading about design patterns . If a thread uses an instance variable inside a synchronized block of code, then it has to update its private copy of the variable with the main copy before using it. Hence, if you are using instance variables inside the synchronized block, you do not need them to be volatile. You need them to be volatile only when you use them outside of the synchronized block. In this case, we are using uniqueInstance outside of the synchronized block and hence we need it to be volatile.

    By the way, Paul, that implementation that you would prefer to use is simple, but not reliable. It can violate the singleton pattern by creating 2 instances if 2 threads creep into the getInstance method at the same time. Hence you need to synchronize the method. Synchronizing the method would synchronize it every time it is called, but you need synchronization only for the first time the method is called when the uniqueInstance variable is null. Once the variable is initialized, you do not need synchronization any more, because no more instance creation is involved and this is where the double checked locking is handy because it applies synchronization only the first time providing significant performance improvement.
    Jeff Albertson
    Ranch Hand

    Joined: Sep 16, 2005
    Posts: 1780
    Originally posted by B Sathish:
    I think I understand now why that variable needs to be volatile. [...] You need them to be volatile only when you use them outside of the synchronized block.


    Careful: the following code is not valid -- why?

    Originally posted by B Sathish:

    By the way, Paul, that implementation that you would prefer to use is simple, but not reliable. It can violate the singleton pattern by creating 2 instances if 2 threads creep into the getInstance method at the same time. Hence you need to synchronize the method.


    That's false, because when a class is loaded, say when getInstance is first encountered, there is a kind of synchronizion going on in the class loading process that stops multiple threads from loading the same class or proceeding before the class is properly loaded. The code given works just fine, as would the following even easier implementation (if you don't mind using the public field...)
    Sometimes I like to write the most clever code I can, but perhaps the best thing to do is accept simpler is better. What's the old saying: if the code you write is as complex as you can make it, who are you going to get to debug it?!
    Jeff Albertson
    Ranch Hand

    Joined: Sep 16, 2005
    Posts: 1780
    Errr... just to complete that last code example, make uniqueInstance final as well...
    B.Sathish
    Ranch Hand

    Joined: Aug 18, 2005
    Posts: 372
    Jeff,
    I agree that this is thread-safe :

    public class Singleton {
    private static Singleton uniqueInstance = new Singleton();
    public static Singleton getInstance() {
    return uniqueInstance;
    }
    }

    What I meant was the classic implementation of the singleton pattern is not thread-safe

    public class Singleton
    {
    private static Singleton uniqueInstance;
    public static Singleton getInstance()
    {
    if (uniqueInstance == null)
    {
    uniqueInstance = new Singleton();
    }
    return uniqueInstance;
    }
    }

    The version that you have given is an example of an eagerly-created singleton instance. While it would be simple and thread-safe for most situations, it has the draw-back that it is resource-intensive as the instance is eagerly created. What if the Singleton instance is a highly resource-intensive object? and what if you cannot say for sure when the singleton instance would be used? and what if there is a chance that it would not be used at all? pre-loading this instance in memory would be a waste of resource right? That is when the classic implementation makes sense as it creates the instance lazily only when needed, but it is not thread-safe. You could make the method synchronized in the classic implementation, but that would apply synchronization every time the method is called . This is where the double-checked locking comes into picture, it applies synchronization only the first time and offers performance improvement and is thread-safe.

    Hence there are situations where you have to go for a more complex version. You cannot generalize that the simpler version will always work in every situation. Every implementation has its trade-offs. In this case it's resource-utilization Vs performance. Your version offers better performance and mine better resource utilization. You cannot blindly choose the simpler version, you need to evaluate these trade-off's, decide what's more important to you and then choose the right implementation
    Jeff Albertson
    Ranch Hand

    Joined: Sep 16, 2005
    Posts: 1780
    Originally posted by B Sathish:
    The version that you have given is an example of an eagerly-created singleton instance. While it would be simple and thread-safe for most situations, it has the draw-back that it is resource-intensive as the instance is eagerly created. What if the Singleton instance is a highly resource-intensive object? and what if you cannot say for sure when the singleton instance would be used? and what if there is a chance that it would not be used at all? pre-loading this instance in memory would be a waste of resource right? That is when the classic implementation makes sense as it creates the instance lazily only when needed, but it is not thread-safe.

    My take on this is that the simpler approach works 99+% of the time. I'm thinking of a Singleton class whose only public static method is getInstance. In this situation (which I've observed is the case in almost all well-written code) the only reason for mentioning the Singleton class in code is that you are about to use it! Hence there is no unnecessary pre-loading. If you can give me a realistic example to the contrary, I think forum members would be interested in seeing it.

    If you are worried about loading being too eager, there is another idiom that can come to the rescue, again based on class loading, not synchronization:(I may have flubbed that because I'm doing it from memory and have never had the need to use it.)
     
    It is sorta covered in the JavaRanch Style Guide.
     
    subject: Question regarding Singleton pattern