private void testForDeadlock(String pathToAcquire) {
        LockStats globalLockStats = LockStats.getGlobal();
        var errorMessage = new StringBuilder().append("Deadlock detected: Thread ").append(thread.getName());

        // The set of all threads waiting.  If we're waiting in a cycle, there is a deadlock...
        Set<Thread> threadsAcquiring = new HashSet<>();
        Thread threadAcquiringLockPath = thread;
        String lockPath = pathToAcquire;

        while (true) {
            Optional<ThreadLockStats> threadLockStats = globalLockStats.getThreadLockStatsHolding(lockPath);
            if (threadLockStats.isEmpty()) {
                return;
            }

            Thread threadHoldingLockPath = threadLockStats.get().thread;
            if (threadAcquiringLockPath == threadHoldingLockPath) {
                // reentry
                return;
            }

            errorMessage.append(", trying to acquire lock ")
                        .append(lockPath)
                        .append(" held by thread ")
                        .append(threadHoldingLockPath.getName());
            if (threadsAcquiring.contains(threadHoldingLockPath)) {
                // deadlock
                getGlobalLockMetrics(pathToAcquire).incrementDeadlockCount();
                logger.warning(errorMessage.toString());
                return;
            }

            Optional<String> nextLockPath = threadLockStats.get().acquiringLockPath();
            if (nextLockPath.isEmpty()) {
                return;
            }

            threadsAcquiring.add(threadAcquiringLockPath);
            lockPath = nextLockPath.get();
            threadAcquiringLockPath = threadHoldingLockPath;
        }
    }
Tries to detect whether acquiring a given lock path would deadlock.

<p>Thread T0 will deadlock if it tries to acquire a lock on a path L1 held by T1,
and T1 is waiting on L2 held by T2, and so forth, and TN is waiting on L0 held by T0.</p>


<p>Since the underlying data structures are concurrently being modified (as an optimization,
no lock is taken for this calculation), a cycle may be detected not involving T0.</p>

<p>This method is a best-effort attempt at detecting deadlocks:  A deadlock may in fact be
resolved even though this method throws, if e.g. locks are released just after this
method.</p>
zkfacade/src/main/java/com/yahoo/vespa/curator/stats/ThreadLockStats.java