A deadlock occurs when two threads (or processes) are waiting for each other to release a resource and thus neither can complete its job since it waits forever.
Two threads wait for a different mutex, which the other thread holds.
A degenerate case is when a single thread is blocked, waiting for a mutex that it already holds (like a dog chasing its own tail.)
How to Avoid Deadlocks:
These notes by Miriam Briskman are licensed under CC BY-NC 4.0 and based on sources.