My question is an extension to this one: Volatile guarantees and out-of-order execution
To make it more concrete, let's say we have a simple class which can be in two states after it is initialized:
class A {
private /*volatile?*/ boolean state;
private volatile boolean initialized = false;
boolean getState(){
if (!initialized){
throw new IllegalStateException();
}
return state;
}
void setState(boolean newState){
state = newState;
initialized = true;
}
}
The field initialized is declared volatile, so it introduces happen-before 'barrier' which ensures that reordering can't take place. Since the state field is written only before initialized field is written and read only after the initialized field is read, I can remove the volatile keyword from declaration of the state and still never see a stale value. Questions are:
- Is this reasoning correct?
- Is it guaranteed that the write to initialized field won't be optimized away (since it changes only the first time) and the 'barrier' won't be lost?
Suppose, instead of the flag, a CountDownLatch was used as an initializer like this:
class A { private /*volatile?*/ boolean state; private final CountDownLatch initialized = new CountDownLatch(1); boolean getState() throws InterruptedException { initialized.await(); return state; } void setState(boolean newState){ state = newState; initialized.countdown(); } }
Would it still be alright?