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