Skip to content

Threading & Deadlocks — Notes#

Debugging deadlocks#

  • Reproduce: stress-test with many threads.
  • Snapshot stacks (jstack, gdb thread apply all bt, tsan).
  • Look for cycles in the held-vs-waiting lock graph.
  • Time-bound tryLock to surface deadlocks fast in tests.

Designing them out#

  • Hold one lock at a time when possible.
  • If you must hold multiple, define a global lock-ordering policy.
  • Prefer message-passing (channels, actors, Kafka) over shared mutable state.
  • Keep critical sections short; never call out into unknown code while holding a lock.

Lock-free isn't a silver bullet#

Lock-free algorithms have their own hazards: ABA, livelocks, memory-ordering bugs. Use battle-tested data structures (ConcurrentHashMap, java.util.concurrent.atomic, c++ std::atomic, Go channels).

Refs#

  • Java Concurrency in Practice — chapter 10 (avoiding liveness hazards).
  • Edsger Dijkstra: original treatment of dining philosophers.
  • The Linux RT-locking and priority inheritance discussions.
  • PostgreSQL docs: deadlocks & advisory locks.