I have a vague memory of this being discussed before, but anyways:
I have a thread dump from a customer with a e.o.cs.dl.u.c.PooledExecutor
that has a thread in WaitWhenBlocked, waiting on the synchronous channel
(Pool was created using new PooledExecutor(maxSize);
Yet I cannot see any active worker thread that would eventually take
over the offered work.
When looking at this, I think I found a race condition between the last
part of #execute after the synchronized block and workerDone().
Assume a pool with maxSize=1, the only worker busy.
T1 in #execute: leaves the synchronized block heading for the
T2 in Worker#run: for example, task.run throws, executes workerDone,
decrements pool size to 0, polls the handOff --- nothing there yet, so
T1 reaches WaitWhenBlocked and waits forever.