I tried to use AddOrUpdate method in ConcurrentDictionary.
From the "Remarks" section on this page https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx. it says
"However, delegates for these methods are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, the code executed by these delegates is not subject to the atomicity of the operation."
So I am not sure whether it is thread safe. I have one case, if the key is not found, the value is 1, otherwise increase the value by 1.
I wrote below function
private static void AddOrUpdate(ConcurrentDictionary<string, int> map)
{
Random r = new Random();
Thread.Sleep(r.Next(10));
map.AddOrUpdate(Key, 1, (key, value) => value + 1);
}
public static void TestThreadSafe(ConcurrentDictionary<string, int> map)
{
Thread[] threads = new Thread[Size];
for (int i = 0; i < Size; ++i)
{
threads[i] = new Thread(() => AddOrUpdate(map));
}
foreach (var thread in threads)
{
thread.Start();
}
}
created about 300,000 threads and run them in parallel. The results are always 300,000.
Is above method thread safe? When is AddOrUpdate not thread safe?
It is thread safe in your usage. It becomes not thread safe when the delegate passed to AddOrUpdate
has side effects, because those side effects may be executed twice for the same key and existing value.
For example:
private static void AddOrUpdate(ConcurrentDictionary<string, int> map)
{
Random r = new Random();
Thread.Sleep(r.Next(10));
map.AddOrUpdate(Key, 1, (key, value) => { Console.WriteLine(key + ": " + value); return value + 1; });
}
May print the same key + value more than once.
What happens is that sometimes the ConcurrentDictionary may execute those methods on multiple threads, then take the resulting value and enter the lock to try and apply it. One of the threads will succeed, and the other will then enter the lock, see that the value has changed since it read it, and try the delegate again.
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