I was going through Java Concurrency In Practice and got stuck at the 8.3.1 Thread creation and teardown topic. The following footnote warn
Seems like it was a bug with older java versions but it doesn't exist now in Java 1.8.
According to the Java 1.8 documentation from ThreadPoolExecutor.execute():
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
* ....
*/
In the second point, there is a recheck after adding a worker to the queue that if instead of queuing the task, a new thread can be started, than rollback the enqueuing and start a new thread.
This is what is happening. During first check the task is queued but during recheck, a new thread is started which executes your task.