shadcn.io is not affiliated with official shadcn/ui
Thread Pool Deadlock Dashboard Block for Vue
Six JVM thread pools with active, idle and queued threads, a list of the threads blocked in the pool you press, and a deadlock finder that names the cycle and lets you interrupt a thread to break it.
Installation
Overview
Find a deadlock in a thread dump with this thread pool panel for Vue with Ark UI. A hairline frame with a plus mark on each corner lists six Threadhurst pools as ruled rows with their active, idle and queued threads and how many are blocked on a lock. Pressing a pool lists its blocked threads as relations: the thread, the lock it waits for and who holds that lock. A depth-first walk over those wait-for edges finds a cycle and says it in a sentence, such as "t-12 waits for a lock held by t-7, which waits for one held by t-12: a deadlock", and marks the threads in it with a loop glyph. "Interrupt t-12" frees that thread's locks in the demo, the cycle breaks and the panel reads "No deadlock". It's built from Badge, Button and Guides. For JVM tooling and incident reviews.
FAQ
How do I load a real thread dump?
Replace POOLS with your pools' counts and WAITS with one entry for each blocked thread: its thread, its pool, the lock it waits for and the holder of that lock. The blocked counts, the header sentence, the relations and the deadlock sentence are all worked out from WAITS. A JVM thread dump lists exactly these fields in its "waiting to lock" and "locked" lines.
How is the deadlock found?
findCycle starts at each waiting thread and follows "waits for a lock held by" until it reaches a thread it has already seen. If it comes back to where it started, that path is a cycle. A thread waiting on a running thread, or behind a deadlocked one, is blocked but not in the cycle, so it carries no loop glyph.
What does Interrupt do?
In the demo it releases the locks held by t-12 and drops its own wait, so the threads that waited on it are free and the cycle is gone. In a real tool this would call your attach API; here nothing is attached. Reset puts the dump back.
What stays local, and how do I wire it for real?
Everything: the dump is typed at a fixed time and no process is touched. To wire it, parse a dump or a management bean for the wait edges, refresh it on an interval you choose, and send the interrupt to your own service with a confirmation.