Detect a Deadlock from Lock Logs
Problem statement
Several threads share locks. You are given a log of lock requests and releases, logs, in the order they happened. Each entry is "<thread> acquire <lock>" or "<thread> release <lock>". A thread and a lock may have the same name; they are still different things.
Replay the log with these rules:
acquire: if the lock is free, the thread now holds it. If another thread holds it, the requesting thread starts waiting for that lock and is blocked.release: the thread gives up the lock. If threads are waiting for it, the one that started waiting earliest now holds it and is no longer blocked. Otherwise the lock becomes free.
A deadlock is a cycle of blocked threads where each thread waits for a lock held by the next thread in the cycle, and the last thread waits for a lock held by the first. None of them can ever run again, so a deadlock never goes away once it forms.
Return true if at least one deadlock exists after the whole log is replayed, and false otherwise. Other threads may keep running while some threads are deadlocked.
Function
hasDeadlock(logs: String[]) → booleanExamples
Example 1
logs = ["t1 acquire A","t2 acquire B","t1 acquire B","t2 acquire A"]return = truet1 holds A and t2 holds B. Then t1 waits for B (held by t2) and t2 waits for A (held by t1). This is a cycle, so the answer is true.
Example 2
logs = ["t1 acquire A","t2 acquire A","t1 acquire B","t1 release B","t1 release A","t2 release A"]return = falset2 waits for A while t1 holds it. t1 keeps running, takes and releases B, then releases A, which goes to t2. t2 releases it later. Nobody is left waiting, so the answer is false.
Example 3
logs = ["t1 acquire A","t2 acquire B","t3 acquire C","t1 acquire B","t2 acquire C","t3 release C","t3 acquire A"]return = falset1waits forB(held byt2) andt2waits forC(held byt3).t3releasesC, sot2gets it and runs again. Thent3waits forA, held byt1.- Now
t3waits fort1, andt1waits fort2, butt2is not blocked. The chain ends, so there is no cycle and the answer isfalse.
Example 4
logs = ["t1 acquire A","t1 acquire B","t1 release B","t1 release A","t2 acquire B","t2 acquire A","t2 release A","t2 release B"]return = falset1 takes A then B, and t2 later takes B then A. This opposite lock order could deadlock in a different run, but here t1 releases both locks before t2 starts, so no thread ever waits. Only an actual deadlock counts, so the answer is false.
Example 5
logs = ["p acquire X","q acquire Y","p acquire Y","q acquire X","r acquire Z","r release Z","s acquire Z","s release Z"]return = truep holds X and waits for Y, while q holds Y and waits for X: a deadlock. Threads r and s keep taking and releasing Z afterwards, but that does not clear the deadlock, so the answer is true.
Constraints
0 <= logs.length <= 1500- Each
logs[i]is"<thread> acquire <lock>"or"<thread> release <lock>", with single spaces. - Thread and lock names have
1to10characters, all letters or digits. - The log is consistent: a waiting thread has no entries until it gets its lock, a thread releases only locks it holds, and a thread never acquires a lock it already holds.