You starved the executor / threadpool. Simple enough.
Why do you have such a tiny threadpool to begin with?
Our threadpool / executor defaults assume reasonable baselines.
Executor impl: QueuedThreadPool
max threads: 200
min threads: 8
idle timeout: 60,000 ms
backed by: BlockingArrayQueue
These are practical limits based on what is considered a modern baseline from 2010.
Suitable for limited devices of the day (such as J2ME, Raspberry Pi, and Android)
These defaults also perform splendidly for larger systems as well.
Your FixedThreadPool executor is a premature optimization that is harming you.