If I use the classic get/compareAndSet, the following case might happen:

T1: if (state.get()) succeeds
T2 if (compareAndSet(true, false)) succeeds
T1: observer.onNext() executing
T2: observer.onCompleted executing

One would need to mutually exclude observer.onXXX calls, which could be done via synchronization and some overhead.