Home > database >  Understanding the thread safety of a List<T>
Understanding the thread safety of a List<T>

Time:10-07

  1. I am trying to understand why it prints Item 0, Item 0 and Item 1
  2. In debugging it prints Item 0, Item 0, Item 1, Item 1

Above bullet in 2 result make sense. Can someone help me understand why it prints bullet in 1?

Taken from C# 9.0 in a Nutshell

class ThreadSafe
{
    static List<string> _list = new List<string>();

    public static void AddItem()
    {
        // lock the list
        lock (_list)
        {
            _list.Add("Item "   _list.Count);
        }
        // Rather than locking for the duration; copy to an array
        string[] items;
        lock (_list)
        {
            items = _list.ToArray();
        }
        foreach (string s in items)
        {
            Console.WriteLine(s);
        }
     }
     static void Main(string[] args)
     {
       new Thread(ThreadSafe.AddItem).Start();
       new Thread(ThreadSafe.AddItem).Start();
     }
}

CodePudding user response:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement

While a lock is held, the thread that holds the lock can again acquire and release the lock. Any other thread is blocked from acquiring the lock and waits until the lock is released.

It will really depend on the environment but the straight forward answer is as follows.

  1. Thread 1 will lock list.
  2. Thread 2 will try to access but can't so it will wait
  3. Thread 1 will add to the list
  4. Thread 2 is still waiting
  5. Thread 1 will release the lock
  6. Thread 2 will lock the list
  7. Thread 1 will try to lock the list but it is already locked so it will wait
  8. Etcetera

It really depends on when the threads actually start computing. But this will be the most logical answer to the output that you are seeing. Running it on a different environment (CPU, etc) might result in different output.

  • Related