It is actually a bit surprising, but many .NET developers have never had deadlocks in their code. Some very good developers may not have seen them for years. So it may be a good time to remind about them.

One the common mistakes about the deadlocks is when they are explained as double locking on the same variable. I've heard a few times that deadlock is locking on the same variable from different threads, which is a bit better but is not all the truth.

When you hear about the deadlock, what should come first to you mind is the dining philosophers problem. Imagine two philosophers, dinner table, two spaghetti bowls, two forks. The philosopher can eat only if he has two forks. Each of the philosophers decided that he will try to take two forks and start eating. Dinner starts. The first philosopher takes one and at the same time the second takes another. Now they look at each other, waiting, questioning "Why should I give my fork?" Well, they starved to death because of their egoes. Perhaps that's where the "dead" in the "deadlocks" came from.

It is a good analogy, but what does it mean in terms of programming? The philosophers, of course, represent computer programs that work in parallel. They may work in different threads or different processes or even on different computers. Forks are lockable entities, such as objects, mutexes, etc. Taking the fork means acquiring the lock on the entity (marking it as currently used exclusively by one philosophers). Putting fork on the table means releasing the lock (marking it as not used currently).

The most minimalistic example of the deadlock in .NET is probably this one:

open System.Threading;
object a = new {}, b = new {};
new Thread(() => { lock (a) { Thread.Sleep(5); lock (b) { } } }).Start();
new Thread(() => { lock (b) { Thread.Sleep(5); lock (a) { } } }).Start();