using System;
using System.Threading;
using System.Threading.Tasks;
namespace InterlockedLearning
{
class Program
{
static int sharedVariable = 0;
static void Main()
{
Parallel.For(0, 1000000, Func1);
Console.WriteLine("Thread{0} sharedVariable: {1}", Thread.CurrentThread.ManagedThreadId, sharedVariable);
Console.Read();
}
public static void Func1(int val)
{
int i = Interlocked.CompareExchange(ref sharedVariable, 0, 0);
if (i < 500000)
{
Interlocked.Increment(ref sharedVariable);
}
}
}
I am studying how to modify the above code so that the race condition problem does not happen again.
The above code result should be 500000, but the code's final result is 500001 if running several times. I think it may be caused by the checking condition.
I understand that it can be solved by simply using a lock, but I wonder if there are any non-blocking style methods to solve the problem.
The general pattern for updating a field using
CompareExchangeis (from MSDN):Adapting this to your scenario:
This says:
There's the possibility of a race, where we read the
sharedVariable, then someone else increments it, then we compare against 500000, but that's OK. If it was >= 500000 before someone else incremented it, it's going to be >= 500000 after they incremented it, too.