runState provides the main lifecyle control, taking on values:
RUNNING: Accept new tasks and process queued tasks
SHUTDOWN: Don't accept new tasks, but process queued tasks
STOP: Don't accept new tasks, don't process queued tasks,
and interrupt in-progress tasks
TERMINATED: Same as STOP, plus all threads have terminated
The numerical order among these values matters, to allow
ordered comparisons.
runState provides the main lifecyle control, taking on values:
RUNNING: Accept new tasks and process queued tasks
SHUTDOWN: Don't accept new tasks, but process queued tasks
STOP: Don't accept new tasks, don't process queued tasks,
and interrupt in-progress tasks
TERMINATED: Same as STOP, plus all threads have terminated
The numerical order among these values matters, to allow
ordered comparisons. The runState monotonically increases over
time, but need not hit each state. The transitions are:
RUNNING -> SHUTDOWN
On invocation of shutdown(), perhaps implicitly in finalize()
(RUNNING or SHUTDOWN) -> STOP
On invocation of shutdownNow()
SHUTDOWN -> TERMINATED
When both queue and pool are empty
STOP -> TERMINATED
When pool is empty