Reading about DCL in Wikipedia,
I was wondering about the problem in DCL and the proposed solution, or in other words why is the volatile
keyword needed?
The problem, in short: using DCL may result in some cases in a partially constructed object being used by thread. The proposed solution (for JAVA 5+):
// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
helper = result = new Helper();
}
}
}
return result;
}
// other functions and members...
}
Now, my question is why not drop the volatile
from helper? correct me if I'm wrong, but if you just break this line: helper = result = new Helper();
to:
result = new Helper();
helper = result;
In this scenario the helper
will never get the reference until the object is complete. Isn't that so? How is the volatile
doing better?
EDIT: assume this code:
class Foo {
private volatile Helper helper;
public Helper getHelper() {
Helper result = helper;
if (result == null) {
synchronized(this) {
result = helper;
if (result == null) {
result = new Helper();
result.someMethod();
helper = result;
}
}
}
return result;
}
}
If the next line after initialization doesn't guaranty a fully initialized object, I can't call methods on it. Can I?