This week's book giveaway is in the Agile and other Processes forum. We're giving away four copies of The Mikado Method and have Ola Ellnestam and Daniel Brolund on-line! See this thread for details.
Hallo, I have a singleton used in multithread environment see the code :
This is a simple registry mechanism. The user can obtain only one instance (the private static Registry registry) via the getInstance method - here I use the D Schmidt's "double checked loocking" so if two (or more) threads try to get an instance only one is created. For the rest of methods I synchronized on this (the unique registry instace) so the rest is also safe.
So what do you all think ?
Regards,Mihai
SCJP, SCJD, SCWCD
Arto Pastinen
Ranch Hand
Joined: Dec 13, 2002
Posts: 79
posted
0
Hi!
Instead synchronizing register, request removeKey and close methods, synchronize values object.
example:
public void close() { synchronized(values) { values.clear(); } }
and other very little performace issue is that you don't have to test is registry null in getInstance.
I usually make singleton class this way:
public class Foo { private static final Foo instance = new Foo();
private Foo() {}
public static Foo getInstance() { return instance; } }
Ed Wallen
Ranch Hand
Joined: Feb 11, 2002
Posts: 34
posted
0
Do not use double-check locking for your Singleton getInstance() method. The bottom line is that double-checked locking, in whatever form, should not be used because you cannot guarantee that it will work on any JVM implementation. JSR-133 is addressing issues regarding the memory model, however, double-checked locking will not be supported by the new memory model.
Double checked locking is pretty well proven broken in multi-threaded and particularly multi-processor applications. It's much simpler and safer to just say:
Ed beat met to this message! I'm back to edit out a link I had that accidentally included smileys or something. I just googled for "java double checked locking broken" and found scads of articles.
Hope that helps! [ March 15, 2005: Message edited by: Stan James ]
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Alan Mehio
Ranch Hand
Joined: Apr 04, 2005
Posts: 70
posted
0
Many thanks to the link it is very nice article to be aware of
Originally posted by Ed Wallen: Do not use double-check locking for your Singleton getInstance() method. The bottom line is that double-checked locking, in whatever form, should not be used because you cannot guarantee that it will work on any JVM implementation...
-Ed
It is only guaranteed to work if the machine designers say so. This is not just for virtual machines but it suffers the same issue running directly on the CPU. So unless your AMD Athlon manual has information supporting this technique, it may fail even with assembly/c/c++.
Mihai Radulescu
Ranch Hand
Joined: Sep 18, 2003
Posts: 912
posted
0
Ok , I also have some news I just read the "Head first design patterns" and on the singleton pattern in multithread environment I found :
.........in the java version 1.4 and earlier , amny JVMs contains implementations of the volatile keyword that allow improper synchronization for the double-checked locking.
Yes I heard there would be work towards making this work in 1.5. I also heard there was work towards making a lock check very quick. Seems a waste to do both.
We just don't need double checked locking. Unless you plan to hit this method LOTS of times, and even then its really not an issue.
If they do claim to have made it work on 1.5, i predict it will only be in certain JVMs and as a result nobody will really be able to use it.
David Harkness
Ranch Hand
Joined: Aug 07, 2003
Posts: 1646
posted
0
Warning: Micro-optimization area ahead. Hard hat must be worn at all times.
If you expect far more calls to request() than the other methods and the size of the map isn't "too large," you can avoid synchronization for request() using copy-on-write. When the Registry needs to modify the values map, it modifies a copy instead and then swaps it in for the real one. Thus, only the modifying methods need to be synchronized.[ Updated after re-reading JLS chapter 17 which states that only long and double suffer from non-atomicity. ]
The only issue is that the JVM is not required to perform the store/write actions to main memory. Thus, it's possible that the map could be swapped out with a new one, but only the thread that performed the swap sees the effect.
Making the variable volatile solves this but is only slightly faster than synchronizing. However, it still allows concurrent access which synchronization does not, which was the point all along (for me, anyway ). [ April 11, 2005: Message edited by: David Harkness ]
I agree. Here's the link: http://ej-technologies/jprofiler - if it wasn't for jprofiler, we would need to
run our stuff on 16 servers instead of 3.