I've done the following test:
private static object threadLocker = new object();
private static long threadStaticVar;
public static long ThreadStaticVar
{
get
{
lock (threadLocker)
{
return threadStaticVar;
}
}
set
{
lock (threadLocker)
{
threadStaticVar = value;
}
}
}
Parallel.For(0, 20000, (x) =>
{
//lock (threadLocker) // works with this lock
//{
ThreadStaticVar++;
//}
});
This Parallel.For invokes the method passing the values from 0 to 19999. So it would execute 20k times.
If I don't wrap ThreadStaticVar++; with a lock, even though it has a lock on its get and set, the result will not be 20000. If I remove the comment bars and lock it inside the .For it gets the right value.
My question is: How does it work? Why the lock on the get and set doesn't work? Why it works only inside my For?
The ++ operator isn't an atomic increment. There will be a call to get followed by a call to set, and those calls can be interleaved among different threads since the lock is only on each individual operation. Think of it like this:
lock {tmp = var}
lock {var = tmp+1}
Those locks don't look so effective now, do they?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With