C# Thread example code working without a lock

Viewed 39

I'm having a play with Threads to remind myself how they work, I haven't done any Threading code in ages.

So I thought I'd start with the most basic example, create n threads, get them updating a static int without a lock, so I can see it go wrong. However, it's working? The final value is 500 every time, it should be slightly random as Threads update the value at the same time

I know I'm doing something really stupid here but I can't see what

https://dotnetfiddle.net/w9TK5W

using System;
using System.Threading;
                    
public class Program
{
    public class Department
    {
        public static int a = 0;

        public Department()
        {            
        }

        public void Inc()
        {
            a = a +5;
            a = a -4;
        }
    }
    
    public static void Main()
    {
        int count = 500;
        Thread[] threads = new Thread[count];
        Department dep = new Department();

        for (int i = 0; i < count; i++)
        {
            Thread t = new Thread(new ThreadStart(dep.Inc));
            threads[i] = t;
        }

        for (int i = 0; i < count; i++)
        {
            threads[i].Start();                
        }

        Thread.Sleep(2000);

        for (int i = 0; i < count; i++)
        {
            threads[i].Join();
        }
        Console.WriteLine(Department.a.ToString());
    }
}

[Edit, more info]

So I changed the loop to look like this, it now works as expected

      int b = a;
        
        b = b+1;
        
        int j=0;
        for (int i=0; i<1E5; i++)
        {
            j += i;
        }
        
        a = b;
1 Answers

The computation in each thread is so short that probably each started thread is already ended before the next one actually starts. This happens just by chance. You should run in each thread a loop that performs millions of operations on a, and then you will probably detect the expected inconsistency.

The question has been edited with millions of operation which do not alter a, thus by chance again, the very few operations that actually alter a don't happen at the same time.

The question has been edited since the previous remark, but now it fails for a different reason than the expected initial one. Reading a, waiting a bit, and altering a based on the read value is obviously not atomic. If the loop simply performed a+=1, you could also see that this apparently trivial operation is not atomic either.

Related