Two services both show requests hanging with low CPU. In the first, `jcmd <pid> Thread.print` shows every thread in a four-thread pool parked in the same stack frame calling a downstream dependency. In the second, five threads are BLOCKED on the same monitor address, one thread holds it. Are these the same problem, and does adding more threads to the pool help either one?
They're different failures with the same visible symptom. The first is pool exhaustion: every worker thread is stuck waiting on a dependency that never responds, usually because there's no timeout on the call — the fix is a timeout on every outbound call, plus a separate bounded pool per dependency (a bulkhead) so one dead dependency can't consume the threads that also serve every other endpoint. The second is lock contention: most threads are simply waiting their turn behind one slow holder of a synchronized block — it isn't a deadlock, it resolves on its own once the holder finishes, and the fix is doing less work inside the lock (move I/O outside it) rather than adding threads. Adding more threads doesn't help either case: in pool exhaustion, the new threads just queue for the same unresponsive dependency; in contention, they just queue for the same lock — in both cases you've added apparent capacity on a dashboard while doing nothing about what the threads are actually blocked on.