Потокобезопасное сложение
class Program
{
private static double totalValue = 0;
private static double AddToTotal(double addend)
{
double initialValue, computedValue;
do
{
initialValue = totalValue;
computedValue = initialValue + addend;
}
while (initialValue != Interlocked.CompareExchange(
ref totalValue, computedValue, initialValue));
return computedValue;
}
static void TestIncrement()
{
totalValue = 0;
int length = 1000;
int subLength = 1000;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
var tasks = new Task[length];
for (int i = 0; i < length; i++)
{
var v = i;
tasks[i] = Task.Factory.StartNew(() =>
{
for (int j = 0; j < subLength; j++)
{
totalValue += 1;
}
});
}
Task.WaitAll(tasks);
stopwatch.Stop();
Console.WriteLine($"Потоко не безопасное {totalValue}, {stopwatch.Elapsed}");
tasks = new Task[length];
totalValue = 0;
Object lockObj = new object();
for (int i = 0; i < length; i++)
{
var v = i;
tasks[i] = Task.Factory.StartNew(() =>
{
for (int j = 0; j < subLength; j++)
{
lock (lockObj)
{
totalValue += 1;
}
}
});
}
Task.WaitAll(tasks);
stopwatch.Stop();
Console.WriteLine($"С использованием Lock {totalValue}, {stopwatch.Elapsed}");
stopwatch.Restart();
totalValue = 0;
tasks = new Task[length];
for (int i = 0; i < length; i++)
{
var v = i;
tasks[i] = Task.Factory.StartNew(() =>
{
for (int j = 0; j < subLength; j++)
{
AddToTotal(1);
}
});
}
Task.WaitAll(tasks);
stopwatch.Stop();
Console.WriteLine($"С использованием Interlocked {totalValue}, {stopwatch.Elapsed}");
}
}