Debugging a JDK Deadlock in 30 Minutes with Fray: A Concurrency Thriller

2025-06-07

While adding integration tests for Fray, the author encountered a deadlock in JDK's ScheduledThreadPoolExecutor triggered by seemingly innocuous code. Leveraging Fray's deterministic replay and schedule visualization, the root cause was quickly identified: In the SHUTDOWN state, FutureTask.get can indefinitely block. This stems from interleaved execution of the schedule and shutdown methods, leaving tasks in limbo. Fray provided a clear view of the thread interleaving, enabling the reproduction and reporting of this JDK concurrency bug.

Development