Getting different answer even after using Join() in threads C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Collections.ObjectModel;
using System.Threading;
namespace JUSTFORPRACTICE
{
class Program
{
    static int total = 0;
    public static void Main()
    {
        Thread t1 = new Thread(fun);
        t1.Start();
        Thread t2 = new Thread(fun);
        t2.Start();
        Thread t3 = new Thread(fun);
        t3.Start();
        t1.Join();
        t2.Join();
        t3.Join();
        Console.WriteLine(total);
    }
    public static void fun()
    {
        for (int i = 1; i <= 10000; i++)
            total++;
    }
}

}

I've read that using Join() we can prevent the main thread from executing the futher statements until the current thread in running.But here each time when I am running i m getting different output.....Why?

Jon Skeet
people
quotationmark

You have three threads running concurrently, all mutating shared state in an unsafe way:

  • The increment isn't atomic, in that it's "read, locally increment, write" - if multiple threads read the same value, then each locally increment, then write, you'll effectively "lose" all but one of those increments.
  • There are no memory barriers to force each thread to read the most recent value of the variable from main memory or write the result back to main memory immediately. Each thread could execute fun as "read from main memory once into a register; increment the register 10001 times; write the result back into main memory"...

If you change total++ to Interlocked.Increment(ref total) then each increment operation will be atomic and is guaranteed to work on fresh data, with the results being visible to all threads immediately.

Moral of the question: be incredibly careful when working with mutable shared data from multiple threads.

people

See more on this question at Stackoverflow