Sample code to illustrate a deadlock by using lock(this) Sample code to illustrate a deadlock by using lock(this) multithreading multithreading

Sample code to illustrate a deadlock by using lock(this)


A deadlock will only occur if you have more than one lock. You need a situation where both threads hold a resource that the other needs (which means there has to be a least two resources, and the two threads have to attempt to acquire them in a different order)

So a simple example:

// thread 1lock(typeof(int)) {  Thread.Sleep(1000);  lock(typeof(float)) {    Console.WriteLine("Thread 1 got both locks");  }}// thread 2lock(typeof(float)) {  Thread.Sleep(1000);  lock(typeof(int)) {    Console.WriteLine("Thread 2 got both locks");  }}

Assuming both threads are started within a second of each others, they will both have time to grab the first lock before anyone gets to the inner lock. Without the Sleep() call, one of the threads would most likely have time to get and release both locks before the other thread even got started.


The idea is that you should never lock on something you cannot control who has access to.

Type objects are singletons visible to every .net piece of code and you cannot control who locks on your "this" object from the outside.

Same thing is for strings: since strings are immutable, the framework keeps just one instance of "hard coded" strings and puts them in a pool (the string is said to be interned), if you write two times in your code the string "hello", you will always get the same abject.

Consider the following example: you wrote just Thread1 in your super private call, while Thread2 is called by some library you are using in a background thread...

void Thread1(){  lock (typeof(int))  {    Thread.Sleep(1000);    lock (typeof(long))      // do something  }}void Thread2(){  lock (typeof(long))  {    Thread.Sleep(1000);    lock (typeof(int))      // do something  }}


Sure, here you go.

Note that the common example for a deadlock is when you acquire multiple locks, and two or more threads end up waiting for each other.

For instance, two threads that locks like this:

Thread 1               Thread 2 Lock "A"               Lock "B" Lock "B"               Lock "A" <-- both threads will stop dead here                                     waiting for the lock to be come                                     available.

However, in this example I didn't bother with that, I just let one thread lock indefinitely. You really don't want to loose control over your locks, so while this is a contrived example, the fact that the background thread can completely block the main thread like this, is bad.

using System;using System.Threading;namespace ConsoleApplication7{    public class Program    {        public static void Main(string[] args)        {            LockableClass lockable = new LockableClass();            new Thread(new ParameterizedThreadStart(BackgroundMethod)).Start(lockable);            Thread.Sleep(500);            Console.Out.WriteLine("calling Reset");            lockable.Reset();        }        private static void BackgroundMethod(Object lockable)        {            lock (lockable)            {                Console.Out.WriteLine("background thread got lock now");                Thread.Sleep(Timeout.Infinite);            }        }    }    public class LockableClass    {        public Int32 Value1 { get; set; }        public Int32 Value2 { get; set; }        public void Reset()        {            Console.Out.WriteLine("attempting to lock on object");            lock (this)            {                Console.Out.WriteLine("main thread got lock now");                Value1 = 0;                Value2 = 0;            }        }    }}