Question

I was reading a book about C# when reached a statement that claims that the following code will produce 20000 increments to the shared count variable and the final value of count will be 20000. When I run it, ii always prints 20000. As far as I remember count++ is not thread safe operation and when Console.WriteLine is removed the printed result is as expected - not 20000 in all cases. Can someone explain why count has 20000 as a final value in this case. and why count++ acts as a thread safe operation.

    private static void testTask()
    {
        Task t1 = new Task(() =>
          {
              for (int i = 0; i < 10000; i++)
              {
                  count++;
                  Console.WriteLine("Thread 1 - {0}", count);
              }
          }
       );

        Task t2 = new Task(() =>
         {
             for (int i = 0; i < 10000; i++)
             {
                 count++;
                 Console.WriteLine("Thread 2 - {0}", count);
             }
         }
      );
        t1.Start();
        t2.Start();
        Task.WaitAll(t1, t2);
        Console.WriteLine("Count - {0}", count);
    }
Was it helpful?

Solution

It isn't actually making it safe, you are just affecting the timing reducing the odds of seeing the effects. Executing i++ takes a fraction of the time Console.Write takes, so you are increasing the odds that the i++ in one thread will be executed during a Console.Write in the other. Run it enough times and you'll probably find the same behavior.


class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 100; i++)
        {
            testTask();
        }

        Console.Read();
    }

    private static void testTask()
    {
        int count = 0;

        Task t1 = new Task(() =>
        {
            for (int i = 0; i < 10000; i++)
            {
                count++;
                //Console.WriteLine("Thread 1 - {0}", count);
            }
        }
       );

        Task t2 = new Task(() =>
        {
            for (int i = 0; i < 10000; i++)
            {
                count++;
                //Console.WriteLine("Thread 2 - {0}", count);
            }
        }
      );
        t1.Start();
        t2.Start();
        Task.WaitAll(t1, t2);
        Console.WriteLine("Count - {0}", count);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top