Рассмотрим следующую нетрадиционную реализацию блокировки с двойной проверкой, которая не использует 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;
}
}
}
Является ли этот код потокобезопасным?
В частности, я спрашиваю о конечном поле и гарантиях, которые оно дает, поэтому вопрос можно переформулировать так: возможно ли, чтобы какой-то поток получил неинициализированный экземпляр Value ?
ОБНОВЛЕНИЕ: удалено упоминание о сеттерах, так что после публикации доступны только чтения