• Post Reply Bookmark Topic Watch Topic
  • New Topic

Double check Idiom for lazy initialization of instance fields  RSS feed

 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I wanted to understand the meaning of double check idiom for lazy initialization of instance fields and was reading an article in "Effective java 2nd Edition". I want to validate my understanding of the topic.
To quote from book
Because there is no locking if the field is already initialized, it is critical that the field be declared volatile


I want to validate the following regarding the usage of volatile
field is declared volatile, and the following statement has completed
field = result = computeFieldValue();

and now variable field is not null.

If another thread is calling the method getField() and has reached the following statement as part of first check
if (result == null) {
, it will find the result to be not null because it is initialized with a volatile variable and hence will always be updated with the latest value rather than cache.

Had the variable field been declared non volatile, chances are that the first if check will return true even if the variable is initialized as chances are that it will read the value from cache.

Please confirm this understanding.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know if "chances are" that it will read the old value from the cache. That implies it's the most likely scenario. We can't know how likely it is in general. Only that it's possible.

If you're studying this as an academic exercise to learn about the Java Memory Model, that's fine. Just be aware that there's never a good reason to do this, even though it can be made to work.
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I need to actually implement something like this in my design and hence trying to understand the finer point. The code without volatile modifier works fine in 2 of the systems that I tried but since the finer print says otherwise, wanted to validate this understanding as I need to publish a design document for the module I am working on.
 
Paul Clapham
Sheriff
Posts: 22819
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nitinram agarwal wrote:I need to actually implement something like this in my design and hence trying to understand the finer point.


For the "academic exercise" that Jeff mentioned?

The code without volatile modifier works fine in 2 of the systems that I tried but since the finer print says otherwise, wanted to validate this understanding as I need to publish a design document for the module I am working on.


How do you know it "works fine"? It's very difficult to test threaded code, and often bugs only appear under heavy load in production. Was that the sort of testing you did?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nitinram agarwal wrote:Hi,
I need to actually implement something like this in my design


For a school project? Maybe. But if it's a real-world app, then no, you don't. There's no reason to use DCL other than to study why it's a bad idea.

If it's a singleton, just use lazy instantiation.

If it's something more complex, use synchronization on the get() methods, or maybe java.util.concurrent.AtomicXxx can help you out.
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In two of the systems I did the testing, it was kind of unit testing where I called the getField method from some n number of threads and put some debug statement to check , how many times the getField method is called along with thread name and everytime there was only 1 invocation of getField() method. I did not see any different behavior between volatile and non volatile in my system but per my understanding the usage of volatile makes sense in the scenario I talked about and hence wanted to validate the fact
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I did some reading and agree that double checking Idiom might break in such situation (yet to go through full details).
If I make the get method as synchronized then I believe I might as well not use the volatile keyword. I think this makes sense?

Regards,
Ramakant
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nitinram agarwal wrote:Hi,
I did some reading and agree that double checking Idiom might break in such situation (yet to go through full details).


That's not the point. It can be guaranteed to not break. But don't use it anyway. There's no reason to use it. There are simpler, less fragile alternatives.

If I make the get method as synchronized then I believe I might as well not use the volatile keyword. I think this makes sense?


If all access to that variable is through synchronized methods, then, correct, you don't gain anything by making it volatile.
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are simpler, less fragile alternatives


Can you please give me some pointers like url where I can read these etc?
 
Paul Clapham
Sheriff
Posts: 22819
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What's wrong with Wikipedia? Double-checked locking
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nitinram agarwal wrote:
There are simpler, less fragile alternatives


Can you please give me some pointers like url where I can read these etc?


In addition to the link that Paul provided, I mentioned two of them above: Use eager instantiation for singletons, and make the get() methods synchronized in more complex cases.
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I should have mentioned the version of java..
I am coding on Java 6.
after looking at the url.. I find the following

As of J2SE 5.0, this problem has been fixed. The volatile keyword now ensures that multiple threads handle the singleton instance correctly.


So coming back to my very first post, I believe the assumption/understanding I have given for the code holds correct.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
nitinram agarwal wrote:I think I should have mentioned the version of java..
I am coding on Java 6.
after looking at the url.. I find the following

As of J2SE 5.0, this problem has been fixed. The volatile keyword now ensures that multiple threads handle the singleton instance correctly.


So coming back to my very first post, I believe the assumption/understanding I have given for the code holds correct.


Argh.

Nobody has said it won't work.

Yes, DCL will work if you do it correctly, including using a volatile variable. That's not the point.

The point is that there is no reason to use this approach, ever. (At least not in Java. I can't speak to other languages' memory models.)
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nitin, you may also want to just reread the first part of the Bloch article you're reading. All the points people are making here are made there as well, except that Bloch is willing to concede that there might be some cases where you might need to avoid synchronization for performance reasons, yet also have lazy instantiation of an instance field. But he clearly suggests avoiding lazy initialization entirely, as the first choice, and doing it with a simple synchronized getter, as the second choice. Those are both on p. 282, the first page of Item 71: Use lazy initialization judiciously.

Yes, your understanding of what Bloch was saying in the later pages appears correct. Except where you said "chances are", as Jeff noted. And except where you tried to omit the volatile modifier.
 
nitinram agarwal
Ranch Hand
Posts: 90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot everyone for your valuable input. It simplified a lot of things.
 
manoj bharal
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Visit http://efectivejava.blogspot.in/ and know how lazy initialization affect the performance.
How lazy can we afford to be???

Effective Java Simplified
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!