Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #30461
| Newsgroups | comp.lang.java.programmer |
|---|---|
| Date | 2014-12-01 18:16 -0800 |
| Message-ID | <d4222d17-944c-4042-a05c-7085aecbb400@googlegroups.com> (permalink) |
| Subject | SingletonFactory and safe publication |
| From | John <xsli2@yahoo.com> |
Hi:
I am reading this article(http://shipilev.net/blog/2014/safe-public-construction/). It says the following code is GOOD:
public class SafeDCLFactory {
private volatile Singleton instance;
public Singleton get() {
if (instance == null) { // check 1
synchronized(this) {
if (instance == null) { // check 2
instance = new Singleton();
}
}
}
return instance;
}
}
I feel disagree, by learning from this article(http://en.wikipedia.org/wiki/Double-checked_locking).
If without 'volatile', the code above has two problems, not one problem: 1)other threads may not see the content of 'instance' which is initiated by constructing thread; 2)It is possible thread A is in the middle of constructing the object, so the reference 'instance' is not null, but what it references maybe an partially initiated object, so thread B may get this partially initiated object, causing crash later on.
Adding 'volatile' only solves the first problem, not the second. According to the second article above, the CORRECT way is:
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) { //1st check
synchronized(this) {
result = helper;
if (result == null) { //2nd check
helper = result = new Helper();
}
}
}
return result;
}
// other functions and members...
}
The article does not explain well why the second problem is prevented. But I think when the constructing thread is doing:
helper = result = new Helper();
if in the middle of constructing(the worst case), 'result' is referencing it, but 'helper' is still null. Other threads will get TRUE for 1st check and go into the block[first if(result==null) block], after getting the lock(the constructing thread must have finished and released the lock), now 'result' becomes the reference pointing to a good, solid object. 2nd check will fail(and avoids constructing).
I would like to ask help to understand why the following code is GOOD. The code uses 'final', instead of 'volatile':
public class FinalWrapper<T> {
public final T value;
public FinalWrapper(T value) {
this.value = value;
}
}
public class Foo {
private FinalWrapper<Helper> helperWrapper;
public Helper getHelper() {
FinalWrapper<Helper> wrapper = helperWrapper;
if (wrapper == null) { //1st check
synchronized(this) {
if (helperWrapper == null) { //2nd check
helperWrapper = new FinalWrapper<Helper>(new Helper());
}
wrapper = helperWrapper;
}
}
return wrapper.value;
}
}
Thank you.
Back to comp.lang.java.programmer | Previous | Next — Next in thread | Find similar | Unroll thread
SingletonFactory and safe publication John <xsli2@yahoo.com> - 2014-12-01 18:16 -0800
Re: SingletonFactory and safe publication Arne Vajhøj <arne@vajhoej.dk> - 2014-12-01 21:34 -0500
Re: SingletonFactory and safe publication Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-02 18:20 -0500
Re: SingletonFactory and safe publication Arne Vajhøj <arne@vajhoej.dk> - 2014-12-02 18:52 -0500
Re: SingletonFactory and safe publication Eric Sosman <esosman@comcast-dot-net.invalid> - 2014-12-03 09:51 -0500
Re: SingletonFactory and safe publication Arne Vajhøj <arne@vajhoej.dk> - 2014-12-03 21:29 -0500
Re: SingletonFactory and safe publication Arne Vajhøj <arne@vajhoej.dk> - 2014-12-03 21:34 -0500
Re: SingletonFactory and safe publication Robert Klemme <shortcutter@googlemail.com> - 2014-12-08 08:48 +0100
Re: SingletonFactory and safe publication Lew <lewbloch@gmail.com> - 2015-01-04 16:15 -0800
csiph-web