Search code examples
c#.netmultithreadinglockinginterlocked

c# lock not working as expected


This class uses lock and Interlocked.

Both increaseCount.with_lock.Run(); and increaseCount.with_interlock.Run(); prints between 96-100.

I am expecting both of them to print always 100. What did I make mistake?

public static class increaseCount {
    public static int counter = 0;
    public static readonly object myLock = new object();
    public static class with_lock {
        public static void Run() {
            List<Thread> pool = new List<Thread>();
            for(int i = 0; i < 100; i++) {
                pool.Add(new Thread(f));
            }
            Parallel.ForEach(pool, x => x.Start());
            Console.WriteLine(counter); //should print 100
        }

        static void f() {
            lock(myLock) {
                counter++;
            }
        }
    }

    public static class with_interlock {
        public static void Run() {
            List<Thread> pool = new List<Thread>();
            for(int i = 0; i < 100; i++) {
                pool.Add(new Thread(f));
            }
            Parallel.ForEach(pool, x => x.Start());
            Console.WriteLine(counter);//should print 100
        }

        static void f() {
            Interlocked.Add(ref counter, 1);
        }
    }
}

Solution

  • In both cases, you start up your threads but you don't wait for them to complete so you don't reach the 100 before you print the result and the app closes.

    If after you start all thread you would wait for all these threads to complete with Thread.Join you would always get the correct result:

    List<Thread> pool = new List<Thread>();
    for (int i = 0; i < 100; i++)
    {
        pool.Add(new Thread(f));
    }
    
    Parallel.ForEach(pool, x => x.Start());
    foreach (var thread in pool)
    {
        thread.Join();
    }
    
    Console.WriteLine(counter);
    

    Note: This seems like a test of some kind, but you should know that blocking multiple threads on a single lock is a huge waste of resources.