A more complex form of deadlock can emerge in a scenario which involves nested locking: two or more competing threads and two or more locks. Here, let's take the simplest case: a scenario with two threads (A and B) working with two locks (L1 and L2).
Let's say that this is what unfolds over the vertical timeline, as the following table reveals:
Time | Thread A | Thread B |
t1 | Attempt to take lock L1 | Attempt to take lock L2 |
t2 | Gets lock L1 | Gets lock L2 |
t3 | <--- In critical section of L1 ---> | <--- In critical section of L2 ---> |
t4 | Attempt to take lock L2 | Attempt to take lock L1 |
t5 | Block on L2 being unlocked | Block on L1 being unlocked |
<waits forever: deadlock> | <waits forever: deadlock> |
It's quite clear that ...