Consider the following non-traditional implementation of double-check locking that does not use volatile:
public class ValueProvider {
private static State state = new Initial();
public static Value getValue() {
return state.getValue();
}
private static class Initial implements State {
@Override
public synchronized Value getValue() {
if (state instanceof Initial) {
Value value = new Value();
value.x = 1;
value.y = 2;
state = new Initialized(value);
return value;
} else {
return state.getValue();
}
}
}
private static class Initialized implements State {
private final Value value;
private Initialized(Value value) {
this.value = value;
}
@Override
public Value getValue() {
return value;
}
}
private interface State {
Value getValue();
}
public static final class Value {
private int x;
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
}
}
Is this code thread-safe ?
Specifically I am asking about the final field and the guarantees it gives, so the question may be reformulated as is that possible for some thread to get a non-initialized instance of Value ?
UPDATE: removed mention about setters, so that only reads are available after publication