private boolean waitOnState(final State targetState, final long waitMs) {
        final long begin = time.milliseconds();
        synchronized (stateLock) {
            boolean interrupted = false;
            long elapsedMs = 0L;
            try {
                while (state != targetState) {
                    if (waitMs > elapsedMs) {
                        final long remainingMs = waitMs - elapsedMs;
                        try {
                            stateLock.wait(remainingMs);
                        } catch (final InterruptedException e) {
                            interrupted = true;
                        }
                    } else {
                        log.debug("Cannot transit to {} within {}ms", targetState, waitMs);
                        return false;
                    }
                    elapsedMs = time.milliseconds() - begin;
                }
            } finally {
                // Make sure to restore the interruption status before returning.
                // We do not always own the current thread that executes this method, i.e., we do not know the
                // interruption policy of the thread. The least we can do is restore the interruption status before
                // the current thread exits this method.
                if (interrupted) {
                    Thread.currentThread().interrupt();
                }
            }
            return true;
        }
    }
Kafka Streams states are the possible state that a Kafka Streams instance can be in.
An instance must only be in one state at a time.
The expected state transition with the following defined states is:

<pre>
                +--------------+
        +&lt;----- | Created (0)  |
        |       +-----+--------+
        |             |
        |             v
        |       +----+--+------+
        |       | Re-          |
        +&lt;----- | Balancing (1)| --------&gt;+
        |       +-----+-+------+          |
        |             | ^                 |
        |             v |                 |
        |       +--------------+          v
        |       | Running (2)  | --------&gt;+
        |       +------+-------+          |
        |              |                  |
        |              v                  |
        |       +------+-------+     +----+-------+
        +-----&gt; | Pending      |     | Pending    |
                | Shutdown (3) |     | Error (5)  |
                +------+-------+     +-----+------+
                       |                   |
                       v                   v
                +------+-------+     +-----+--------+
                | Not          |     | Error (6)    |
                | Running (4)  |     +--------------+
                +--------------+


</pre>
Note the following:
- RUNNING state will transit to REBALANCING if any of its threads is in PARTITION_REVOKED or PARTITIONS_ASSIGNED state
- REBALANCING state will transit to RUNNING if all of its threads are in RUNNING state
- Any state except NOT_RUNNING, PENDING_ERROR or ERROR can go to PENDING_SHUTDOWN (whenever close is called)
- Of special importance: If the global stream thread dies, or all stream threads die (or both) then
  the instance will be in the ERROR state. The user will not need to close it.
streams/src/main/java/org/apache/kafka/streams/KafkaStreams.java