Wednesday, March 12, 2025

Understanding thread synchronization in C#


lock (sharedObj1)
{
   ...
   lock (sharedObj2)
   {
       ...
   }
}

Be aware that the order of the locks within the Thread2Work technique has been modified to match the order in Thread1Work. First a lock is acquired on sharedObj1, then a lock is acquired on sharedObj2.

Right here is the revised model of the entire code itemizing:


class DeadlockDemo
{
    non-public static readonly object sharedObj1 = new();
    non-public static readonly object sharedObj2 = new();
    public static void Execute()
    {
        Thread thread1 = new Thread(Thread1Work);
        Thread thread2 = new Thread(Thread2Work);
        thread1.Begin();
        thread2.Begin();
        thread1.Be a part of();
        thread2.Be a part of();
        Console.WriteLine("Completed execution.");
    }
    static void Thread1Work()
    {
        lock (sharedObj1)
        {
            Console.WriteLine("Thread 1 has acquired a shared useful resource 1. " +
                "It's now ready for buying a lock on useful resource 2");
            Thread.Sleep(1000);
            lock (sharedObj2)
            {
                Console.WriteLine("Thread 1 acquired a lock on useful resource 2.");
            }
        }
    }
    static void Thread2Work()
    {
        lock (sharedObj1)
        {
            Console.WriteLine("Thread 2 has acquired a shared useful resource 2. " +
                "It's now ready for buying a lock on useful resource 1");
            Thread.Sleep(1000);
            lock (sharedObj2)
            {
                Console.WriteLine("Thread 2 acquired a lock on useful resource 1.");
            }
        }
    }
}

Consult with the unique and revised code listings. Within the authentic itemizing, threads Thread1Work and Thread2Work instantly purchase locks on sharedObj1 and sharedObj2, respectively. Then Thread1Work is suspended till Thread2Work releases sharedObj2. Equally, Thread2Work is suspended till Thread1Work releases sharedObj1. As a result of the 2 threads purchase locks on the 2 shared objects in reverse order, the result’s a round dependency and therefore a impasse.

Within the revised itemizing, the 2 threads purchase locks on the 2 shared objects in the identical order, thereby making certain that there isn’t any chance of a round dependency. Therefore, the revised code itemizing exhibits how one can resolve any impasse scenario in your utility by making certain that every one threads purchase locks in a constant order.

Greatest practices for thread synchronization

Whereas it’s typically essential to synchronize entry to shared sources in an utility, you should use thread synchronization with care. By following Microsoft’s greatest practices you possibly can keep away from deadlocks when working with thread synchronization. Listed here are some issues to bear in mind:

  • When utilizing the lock key phrase, or the System.Threading.Lock object in C# 13, use an object of a non-public or protected reference kind to determine the shared useful resource. The thing used to determine a shared useful resource will be any arbitrary class occasion.
  • Keep away from utilizing immutable varieties in your lock statements. For instance, locking on string objects might trigger deadlocks because of interning (as a result of interned strings are basically international).
  • Keep away from utilizing a lock on an object that’s publicly accessible.
  • Keep away from utilizing statements like lock(this) to implement synchronization. If the this object is publicly accessible, deadlocks might outcome.

Be aware that you should utilize immutable varieties to implement thread security while not having to jot down code that makes use of the lock key phrase. One other technique to obtain thread security is by utilizing native variables to restrict your mutable knowledge to a single thread. Native variables and objects are all the time confined to at least one thread. In different phrases, as a result of shared knowledge is the foundation reason for race circumstances, you possibly can eradicate race circumstances by confining your mutable knowledge. Nonetheless, confinement defeats the aim of multi-threading, so can be helpful solely in sure circumstances.


Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles

PHP Code Snippets Powered By : XYZScripts.com