I have class designed for lazy initialization and storing objects which creation is not necessary threadsafe. Here is the code:
class SyncTest {
private static final Object NOT_INITIALIZED = new Object();
private Object object;
/**
* It's guaranteed by outer code that creation of this object is thread safe
* */
public SyncTest() {
object = NOT_INITIALIZED;
}
public Object getObject() {
if (object == NOT_INITIALIZED) {
synchronized (NOT_INITIALIZED) {
if (object == NOT_INITIALIZED) {
final Object tmpRef = createObject();
object = tmpRef;
}
}
}
return object;
}
/**
* Creates some object which initialization is not thread safe
* @return required object or NOT_INITIALIZED
* */
private Object createObject() {
//do some work here
}
}
Here final variable tmpRef is used for storing created object before assigning it to checked variable object . This works in tests but I can't say it's correct for sure and won't be optimsed by compiler.
Can this appraoch be used or object field must be declared as volatile?
Also variant with wrapper class was considered where the line
final Object tmpRef = createObject();
must be replaced with this one:
Object tmpRef = new FinalWrapper(createObject()).getVal();
Wrapper class looks like this:
private class FinalWrapper {
private final Object val;
public FinalWrapper(Object val) {
this.val = val;
}
public Object getVal() {
return val;
}
}
Can some of this examples be safely used in multithreaded environment (especially variant with final local field)?