private void notifyListeners(State state, @Nullable T startArg, @Nullable U stopArg,
                                 @Nullable V startResult) {
        for (L l : listeners) {
            try {
                switch (state) {
                    case STARTING:
                        notifyStarting(l, startArg);
                        break;
                    case STARTED:
                        notifyStarted(l, startArg, startResult);
                        break;
                    case STOPPING:
                        notifyStopping(l, stopArg);
                        break;
                    case STOPPED:
                        notifyStopped(l, stopArg);
                        break;
                    default:
                        throw new Error("unknown state: " + state);
                }
            } catch (Exception cause) {
                notificationFailed(l, cause);

                // Propagate the exception if notifyStarting throws an exception.
                if (state == State.STARTING) {
                    throw new IllegalStateException("Failed to start: " + cause, cause);
                }
            }
        }
    }
A synchronous version of {@link #stop(Object)}. Exceptions occurred during shutdown are reported to
{@link #closeFailed(Throwable)}. No argument (i.e. {@code null}) is passed.
core/src/main/java/com/linecorp/armeria/common/util/StartStopSupport.java