aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Double-checked locking and the Singleton pattern ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Double-checked locking and the Singleton pattern ?" Watch "Double-checked locking and the Singleton pattern ?" New topic
Author

Double-checked locking and the Singleton pattern ?

Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Howdy,

trying to implement a thread-safe singleton using the double-checked locking technique my IDE (NetBeans IDE 6.7.1) automatically detects my intention and subsequently marks this with a warning message.
I just applied this technique in the way as it was proposed in the book "Head first design patterns" by the well-known Freeman-guys, Kathy Sierra & Bert Bates.
Besides this having also read a very ineresting ibm-article about this issue on http://www.ibm.com/developerworks/java/library/j-dcl.html, I am not sure any more if double-checked locking is an eligible and valid way to really provide thread safety ?

Kind regards,
Andy


SCJP, SCJD
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Hi Andy,

I created my singleton just like this:
As you see nothing fancy, just simple and easy.

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

yes, of course you're right. This is the possibly simplest way to create a threadsafe singelton.

But what, if I want to create a singleton with a lazy loading behaviour?
The way you did it, is creating it eagerly, i.e. the constructor is called instantly when the class is loaded.
Since the singelton I use has a lot of work to accomplish when being created (reading and parsing the database
file for example), I want to have this done not when the server is started but rather when the singelton is first requested.

So, how can you create a threadsafe singleton with lazy instantiation behavior?
I am not sure, wether double checked locking is the correct answer?

The code, marked as not threadsafe by my IDE looks like the following:


Thanks,
Andy
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Hi Andy,

Maybe you have to implement the "initialization on demand holder idiom", which can be found here.
I'm wondering about how you will pass the path to database file to your singleton.

Kind regards,
Roel
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

the requirement of my special assignment says, that the database file has to be located in the current working directory.
This is why I don't have to pass anything, just having to retrieve the path dynamically.

Thanks for the "initialization on demand holder idiom", this is really cool stuff !
The most amazing about this is, that this technique has lazy behaviour without the need to synchronize.

Besides, I detected the error in my solution:
I forgot to apply the keyword volatile on the instance variable:


My IDE goes fine with this now, however, the "initialization on demand holder idiom" seems to be far more effectively to me.

Kind regards,
Andy
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Andy Jung wrote:the requirement of my special assignment says, that the database file has to be located in the current working directory.
This is why I don't have to pass anything, just having to retrieve the path dynamically.
Are you sure about this? Because it's the very first time I hear about this requirement.

My assignment says:
Such configuration information must be stored in a file called suncertify.properties which must be located in the current working directory.
And that's a complete other story.

By the way, I would advice against the use of keyword "volatile".

Kind regards,
Roel
Kai Witte
Ranch Hand

Joined: Jul 17, 2004
Posts: 354
The IBM article you mentioned is not up to date. With the implementation of JSR 133 in 1.5, double-checked locking can be used.


Kai Witte's business website Kai Witte's private homepage Mock exam / preparation kit reviews
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

Roel De Nijs wrote:
Andy Jung wrote:the requirement of my special assignment says, that the database file has to be located in the current working directory.
This is why I don't have to pass anything, just having to retrieve the path dynamically.
Are you sure about this? Because it's the very first time I hear about this requirement.

No I'm not sure ;-), thanks for your hint ...
Roel De Nijs wrote:[
My assignment says:
Such configuration information must be stored in a file called suncertify.properties which must be located in the current working directory.
And that's a complete other story.

My assignment says the same ;-) ...

But anyway, does this matter? I mean, my singleton can access the property-file and retrieve the path to the database file, because it knows, that the property file has to be located in the current working directory.
This way I don't have to pass the file-path to the constructor of my DataFileAccess class (implemented as a singleton), or do I?

Kind regards,
Andy
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Hi Andy,

I faced the same problem as you: how do I pass the necessary information to my Data class? I just created an init-method in my own interface (extending sun's) which has a parameter to pass the database file location. Of course this method has to be invoked before any other method invocation on Data instance.
I never thought of your approach (just reading the properties file), because you know its location. But in my opinion it is not the best possible approach.

Kind regards,
Roel
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

your solution sounds interesting. But how can you assure, that your method passing the vital information is called before any other methods ? There's no guarantee that Sun's automated Unit tests running against your Data-class conform to your intentions?

So, tell me, how did you encounter this problem?

Kind regards,
Andy
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Hi Andy,

I clearly javadoc'ed this requirement (and also explained in choices.txt). And an IllegalStateException is thrown when you try to invoke another method before the init-method.

Kind regards,
Roel
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

ok, I understand.
But wasn't your approach actually very risky?

Just imagine what would have happened, if, before any human being or assessor had taken a look on your choices.txt or javadocs, an automated tool like JUnit tests ran against your implementation of Sun's provided DB interface?

Because of your runtime-exception thrown it might have resulted in an automated failure. The exam would have been assessed no further and you would have failed :-(.

Is this worth it?
So even if my approach is not the most elegant one and even not flexible to future changes of requirements, I think it is very reliable.

Kind regards,
Andy
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 4913
    
  10

Hi Andy,

I don't want to scare you (or make you question your approach again), BUT I don't agree with
So even if my approach is not the most elegant one and even not flexible to future changes of requirements, I think it is very reliable.


You are using singleton design pattern, which requires your Data constructor to be private, so when the JUnit test case tries something likeI guess you'll see the problem, not reliable at all

My good buddy Roberto Perillo told me he also had a singleton design pattern and had besides the expected getInstance() also a getInstance(String dbLocation) variant. And he passed with that approach, so that was for me an assurance that singleton design pattern is allowed and that you won't automatically fail.

Kind regards,
Roel
Andy Jung
Ranch Hand

Joined: Feb 07, 2010
Posts: 150
Hi Roel,

actually I didn't realize the Data-class as a singleton.
The Data class just references a DAO (= Data access object, conforming to the DAO design pattern).
This DAO itself is a facade (conforming to the facade design pattern) holding two singeltons:

  • an eagerly created singelton named LockManager responsible for logical record locking
  • a lazily created singelton named DataFileReader responsible for accessing the database file

  • So actually there's no risk with this approach, because the Data class has a normal constructor.

    So, any further arguments versus my approach of retrieving the database file location dynamically in singelton DataFileReader ;-) ?

    Kind Regards,
    Andy
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 4913
        
      10

    Hi Andy,

    My mistake. I was a bit to focused on my solution, so didn't think of the facade design pattern applied to the Data class. But you are right: no restrictions on Data class, so very reliable approach. Well done

    If you think about high cohesion (reading properties file is not the task of your DataFileReader) I don't have any arguments about your approach.

    Kind regards,
    Roel
    Andy Jung
    Ranch Hand

    Joined: Feb 07, 2010
    Posts: 150
    Roel De Nijs wrote:
    If you think about high cohesion (reading properties file is not the task of your DataFileReader) I don't have any arguments about your approach.


    Yes, this is a flaw as I stated before. But I am a "Beckenrandschwimmer" (as a Dutch do you understand this German word ?), so I accept this design flaw in favor of a very risky but more flexible solution.

    Kind regards,
    Andy
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 4913
        
      10

    Hi Andy,

    I'm a Dutch speaker from Belgium, but I don't know the word. Even my dictionary doesn't know it

    I passed with my approach with a nice score and a whole lot others passed too with creating own interface, using singleton pattern for the data class (marking constructor private),... So I think if you have a similar approach it is not that risky...

    Kind regards,
    Roel
    Paul Clapham
    Bartender

    Joined: Oct 14, 2005
    Posts: 18129
        
        8

    Andy Jung wrote:Hi Roel,

    yes, of course you're right. This is the possibly simplest way to create a threadsafe singelton.

    But what, if I want to create a singleton with a lazy loading behaviour?
    The way you did it, is creating it eagerly, i.e. the constructor is called instantly when the class is loaded.
    Since the singelton I use has a lot of work to accomplish when being created (reading and parsing the database
    file for example), I want to have this done not when the server is started but rather when the singelton is first requested.


    Perhaps I'm missing some background information here, but normally classes are not loaded until the first time they are requested. So normally, the behaviours you call "lazy" and "eager" in this context are identical.

    But perhaps there's some reason why this class would be loaded when the server starts?
    Andy Jung
    Ranch Hand

    Joined: Feb 07, 2010
    Posts: 150
    Hi Roel,

    Roel wrote:
    I'm a Dutch speaker from Belgium, but I don't know the word. Even my dictionary doesn't know it
    Roel


    Well, it's actually a composed word consisting of three parts:
    Beckenrandschwimmer = Becken + Rand + Schwimmer;
    Becken = pool;
    rand = edge;
    Schwimmer = swimmer;

    ... actually it's a funny word for someone who always swims to the edge of the pool, because he fears that he might drown

    Best regards,
    Andy
    Andy Jung
    Ranch Hand

    Joined: Feb 07, 2010
    Posts: 150
    Paul Clapham wrote:
    But perhaps there's some reason why this class would be loaded when the server starts?
    Andy Jung
    Ranch Hand

    Joined: Feb 07, 2010
    Posts: 150
    Hi Paul,

    Paul Clapham wrote:
    But perhaps there's some reason why this class would be loaded when the server starts?


    As I said before, between the DB-interface and the DataFileAccess-class, there is a facade-class holding references to the logical LockManager and the DataFileAccess.
    Maybe I'm missing some background, but I thought when declaring DataFileAccess as instance variable in the way:


    the class loader begins loading the class in the VM.
    In this context, eager and lazy-implementations behaves differently to me.

    But maybe I didn't get the point?

    Regards,
    Andy
    Roel De Nijs
    Bartender

    Joined: Jul 19, 2004
    Posts: 4913
        
      10

    Andy Jung wrote:it's actually a composed word consisting of three parts
    I was able to recognize these 3 parts, but not give it a meaning which makes sense in the context you used it. I kept thinking about "someone living on the edge", but that's the complete opposite

    Paul Clapham wrote:But perhaps there's some reason why this class would be loaded when the server starts?
    Normally the server's sole purpose in this assignment is to expose the Data class (fat client) or some business layer (which refers to a Data instance, thin client). So when the server starts, the Data class should be initialized immediately, because it is quiet useless to have your server up and running if the database file doesn't exist or is empty or is not a database file (contains wrong magic cookie)

    Kind regards,
    Roel
    Andy Jung
    Ranch Hand

    Joined: Feb 07, 2010
    Posts: 150
    Roel De Nijs wrote:
    Normally the server's sole purpose in this assignment is to expose the Data class (fat client) or some business layer (which refers to a Data instance, thin client). So when the server starts, the Data class should be initialized immediately, because it is quiet useless to have your server up and running if the database file doesn't exist or is empty or is not a database file (contains wrong magic cookie)


    That's a good argument for creating an eager singleton rather than a lazy one.
    Thanks Roel for your advice, I can use your arguments directly for my choices.txt !

    Regards
    Andy
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Double-checked locking and the Singleton pattern ?
     
    Similar Threads
    Singleton class + Lazy loading
    Want to know why this is not a threading issue ?
    Double-checked locking and Singleton
    Singleton Class with Threads
    Double-checked locking and Singleton