Reputation: 762
I am trying to understand multi-threading and I have the following code and I need to ensure thread safety (typically without using lock statement) by getting the final result 10,000,000, but if you run the following code multiple time in VS you get different values close to 10,000,000 but never reaches it, so I need to fix this code without using lock statement.
using System;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
private static int _counter = 0;
private static void DoCount()
{
for (int i = 0; i < 100000; i++)
{
_counter++;
}
}
static void Main(string[] args)
{
int threadsCount = 100;
Thread[] threads = new Thread[threadsCount];
//Allocate threads
for (int i = 0; i < threadsCount; i++)
threads[i] = new Thread(DoCount);
//Start threads
for (int i = 0; i < threadsCount; i++)
threads[i].Start();
//Wait for threads to finish
for (int i = 0; i < threadsCount; i++)
threads[i].Join();
//Print counter
Console.WriteLine("Counter is: {0}", _counter);
Console.ReadLine();
}
}
}
appreciate your help.
Upvotes: 1
Views: 1808
Reputation: 117175
You're better off getting an understanding of threads, but then moving on quickly to a library that abstracts the complexity for you.
If you use Microsoft's Reactive Framework (aka Rx) - NuGet System.Reactive
and add using System.Reactive.Linq;
- then you can do this:
void Main()
{
var query =
from n in Observable.Range(0, 100)
from x in Observable.Start(() => DoCount())
select x;
var counter = query.Sum().Wait();
Console.WriteLine("Counter is: {0}", counter);
Console.ReadLine();
}
private int DoCount()
{
int counter = 0;
for (int i = 0; i < 100000; i++)
{
counter++;
}
return counter;
}
Much easier and with the result: Counter is: 10000000
Upvotes: 1
Reputation: 67489
Yes, the Interlocked
class of functions are the way to go for lock-free multi-threaded synchronization. In your specific case, you want Interlocked.Increment
Upvotes: 1