public T trySet(T newState) {
    checkState(!Thread.holdsLock(lock), LOCK_HELD_ERROR_MSG);
    requireNonNull(newState, STATE_IS_NULL);

    T oldState;
    FutureStateChange<T> oldFutureStateChange;
    ImmutableList<StateChangeListener<T>> curStateChangeListeners;
    synchronized (lock) {
      if (state.equals(newState) || isTerminalState(state)) {
        return state;
      }

      oldState = state;
      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 oldState;
  }
Tries to change the state. State will not change if the new state {@code .equals()} the current
state, of if the current state is a terminal state. If the state changed, listeners and waiters
will be notified.

@return the state before the possible state change
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/StateMachine.java