public boolean compareAndSet(T expectedState, T newState) {
    checkState(!Thread.holdsLock(lock), LOCK_HELD_ERROR_MSG);
    requireNonNull(expectedState, "expectedState is null");
    requireNonNull(newState, STATE_IS_NULL);

    FutureStateChange<T> oldFutureStateChange;
    ImmutableList<StateChangeListener<T>> curStateChangeListeners;
    synchronized (lock) {
      if (!state.equals(expectedState)) {
        return false;
      }

      // change to same state is not a change, and does not notify the notify listeners
      if (state.equals(newState)) {
        return false;
      }

      checkState(
          !isTerminalState(state), "%s cannot transition from %s to %s", name, state, newState);

      state = newState;

      oldFutureStateChange = this.futureStateChange.getAndSet(new FutureStateChange<>());
      curStateChangeListeners = ImmutableList.copyOf(this.stateChangeListeners);

      // if we are now in a terminal state, free the listeners since this will be the last
      // notification
      if (isTerminalState(state)) {
        this.stateChangeListeners.clear();
      }
    }

    fireStateChanged(newState, oldFutureStateChange, curStateChangeListeners);
    return true;
  }
Sets the state if the current state {@code .equals()} the specified expected state. If the new
state does not {@code .equals()} the current state, listeners and waiters will be notified.

@return true if the state is set
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/StateMachine.java