gpt4 book ai didi

c# - ConcurrentDictionary 中的 AddOrUpdate 线程安全吗?

转载 作者:太空狗 更新时间:2023-10-30 00:49:16 26 4
gpt4 key购买 nike

我尝试在 ConcurrentDictionary 中使用 AddOrUpdate 方法。

来自本页的“备注”部分 https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx .它说

"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."

所以不确定是不是线程安全的。我有一种情况,如果找不到key,则值为1,否则将值增加1。

我在下面写了函数

    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();
}
}

创建了大约 300,000 个线程并并行运行它们。结果总是 300,000。

以上方法线程安全吗? AddOrUpdate 什么时候不是线程安全的?

最佳答案

它在您的使用中是线程安全的。当传递给 AddOrUpdate 的委托(delegate)有副作用时,它变得不是线程安全的,因为对于相同的键和现有值,这些副作用可能会执行两次。

例如:

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; });
}

可能多次打印相同的键+值。

发生的情况是,有时 ConcurrentDictionary 可能会在多个线程上执行这些方法,然后获取结果值并进入锁定以尝试应用它。其中一个线程会成功,另一个线程会进入锁,看到值在读取后发生了变化,然后再次尝试委托(delegate)。

关于c# - ConcurrentDictionary 中的 AddOrUpdate 线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39156752/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com