• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

'double checked locking' in singleton - not thread safe

 
Ranch Hand
Posts: 3852
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I read that even 'double checked locking' is not thread safe. Thread one can get out of synchronized block before JVM assign instance to singleton reference, in that case, thread two will enter into synchronized block and pass the if condition (as singleton is not initialized) and create another instance.

If that can happen then *anything* can happen. JVM is supposed to execute code sequentially until it's specified NOT to do so.

I am totally lost now.
[ June 06, 2007: Message edited by: ankur rathi ]
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

JVM is supposed to execute code sequentially until it's specified NOT to do so.



Actually the JVM is allowed a certain amount of freedom to mess about with that while optimizing. And it can keep data in temporary memory (I imagine registers in hardware) a while before it puts it back in the real variable.

Here's a sane summary of DCL from the Java Specialist newsletter.

When you read my theoretical proofs, you will think I am very clever, thus enabling me to raise my rates next time you ask for help. At the same time, the problems described only happen on a fast multi-processor machine, and it is unlikely that you have one of those standing at home, so you cannot even contradict me.

...

I have tried to gather some evidence that with the current JVM implementations the problem can occur. I have written test code and executed it on a friend's multi-processor. I was not successful in proving my assertions. I have spoken to a number of authors who have written about this problem, and they also do not have firm evidence that this occurs in the real world. I therefore offer no proof or even claim that what I wrote about in this newsletter is true.

That is really all I have to say about the matter. Avoid the double-checked locking to avoid synchronization. In JDK 1.5 they are tidying up the memory model thus showing more clearly that DCL is broken. In the meantime, try not to be too clever ;-)


[ June 06, 2007: Message edited by: Stan James ]
 
Ranch Hand
Posts: 1970
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is educational to read all about this stuff, but the quick thing to take away is: -

Never try to do something "clever" to avoid synchronisation - it probably won't work and, even if it does, it won't save a worthwhile amount of time.

Use synchronisation in a simple, obvious fashion, to control threads' access to shared data, and no-one will get hurt.
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yup. Keep it simple. At the top of that complex Java Specialists newsletter, he recommends my favorite form:

About as simple as you could want with no synchronization. And even a synchronized getInstance() that checks for null is not going to block other threads long enough to worry about, especially since Sun warns us not to use Java in apps that are all that sensitive to the occasional delay.
 
Bartender
Posts: 6663
5
MyEclipse IDE Firefox Browser Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

And even a synchronized getInstance() that checks for null is not going to block other threads long enough to worry about, especially since Sun warns us not to use Java in apps that are all that sensitive to the occasional delay.



I agree. You should do that when you dont have the choice of eager instantiation. But DCL is fixed with Java 5 and above. I would still rather use eager instantiation or a synchronized getInstance() to avoid confusion.
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[John Meyers]: But DCL is fixed with Java 5 and above.

That's only if you make the instance field volatile. The original DCL did not use volatile, and is still broken. And using volatile with DCL wasn't guaranteed to work correctly prior to JDK 5.

I agree that using eager instantiation is simpler, and thus, often preferable. But there are some cases where the initialization is expensive, and may not even be needed for some programs, so lazy instantiation can make sense. In that case, this works:

Or at least, it works as well as Singleton ever works. Meaning if you've got multiple classloaders, or a distributed computing environment, you probably need to try something else.
 
Deepak Bala
Bartender
Posts: 6663
5
MyEclipse IDE Firefox Browser Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


That's only if you make the instance field volatile. The original DCL did not use volatile, and is still broken. And using volatile with DCL wasn't guaranteed to work correctly prior to JDK 5.



Totally agree.

But there are some cases where the initialization is expensive, and may not even be needed for some programs, so lazy instantiation can make sense



Yep ! You cant avoid lazy instantiation sometimes. Agree there too
 
reply
    Bookmark Topic Watch Topic
  • New Topic