One GET /api/lock/contend?workers=16&holdMillis=20 call: 16 threads release simultaneously (via a CountDownLatch) and fight over one synchronized block that holds for 20 ms. One thread enters immediately; 15 queue up. jdk.JavaMonitorEnter records each waiter's queueing time. $ jfr print --events jdk.JavaMonitorEnter recordings/live-demo.jfr | head -15 jdk.JavaMonitorEnter { startTime = 09:59:07.393 (2026-10-01) duration = 20.4 ms monitorClass = java.lang.Object (classLoader = bootstrap) previousOwner = "pool-135-thread-1" (javaThreadId = 365) address = 0x7FCAB40A4860 eventThread = "pool-135-thread-16" (javaThreadId = 380) stackTrace = [ com.ankurm.jfr.service.WorkloadService.holdLedger(int) line: 100 com.ankurm.jfr.service.WorkloadService.lambda$contend$0(CountDownLatch, CountDownLatch, AtomicLong, int) line: 89 java.util.concurrent.Executors$RunnableAdapter.call() line: 545 java.util.concurrent.FutureTask.run() line: 328 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor$Worker) line: 1090 ] } $ jfr print --events jdk.JavaMonitorEnter recordings/live-demo.jfr | grep duration | sort | uniq -c 1 duration = 101 ms 1 duration = 122 ms 1 duration = 142 ms 1 duration = 162 ms 1 duration = 182 ms 1 duration = 20.4 ms 1 duration = 203 ms 1 duration = 223 ms 1 duration = 243 ms 1 duration = 263 ms 1 duration = 283 ms 1 duration = 303 ms 1 duration = 40.6 ms 1 duration = 60.9 ms 1 duration = 81.0 ms 15 events, one per waiting thread, stepping up in ~20 ms increments (20.4, 40.6, 60.9, 81.0, 101, 122, ... 303 ms) -- exactly the signature of 16 threads queueing one at a time for a monitor held 20 ms at a time: the Nth waiter waits roughly (N-1) x 20 ms. The total wall-clock time the HTTP endpoint reported for this call was 326 ms, consistent with the last waiter's ~303 ms queueing time plus its own 20 ms hold.