Deadlocks and livelocks
When a thread cannot continue because it requires some resource that another thread has ownership of, it blocks waiting for that resource. The thread that owns that resource in turn requires something the first thread owns and so it blocks the initial one. Neither can make progress, and this is called a deadlock.
If the resource is preemptable, then the operating system or virtual machine can take the lock away from one of the threads and then another thread will be able to grab it; with this, progress would be made eventually. This is not a deadlock. Also, the resources in question must not be shareable, otherwise both threads could simply acquire the lock at the same time, which would also not be a deadlock.
One way to avoid a deadlock is to ensure that threads request the ownership of a resource in the same order. If we have threads t1 and t2 and they both require r1 and r2, then if they always request lock(r1) followed by lock(r2), it is impossible to get into...