ConcurrentDictionary.GetOrAdd() 是否保证每个键仅调用一次 valueFactoryMethod

作者:编程家 分类: c++ 时间:2025-11-28

ConcurrentDictionary.GetOrAdd() 是否保证每个键仅调用一次 valueFactoryMethod?

ConcurrentDictionary.GetOrAdd() 是 .NET 平台提供的一种线程安全的字典实现,它允许同时访问和修改字典的操作。当我们使用 GetOrAdd() 方法向字典中添加键值对时,我们可能会想知道是否保证每个键仅调用一次 valueFactoryMethod。

答案是,ConcurrentDictionary.GetOrAdd() 方法确保每个键只调用一次 valueFactoryMethod。这意味着如果多个线程同时尝试访问同一个键,只有一个线程会调用 valueFactoryMethod 来生成对应的值,并将其添加到字典中。其他线程将等待该值生成完毕后直接返回。这样可以避免多个线程重复执行 valueFactoryMethod 的开销。

示例代码:

csharp

using System;

using System.Collections.Concurrent;

class Program

{

static void Main(string[] args)

{

var dict = new ConcurrentDictionary();

string key = "key1";

int value = dict.GetOrAdd(key, GenerateValue);

Console.WriteLine($"The value of key '{key}' is {value}");

key = "key2";

value = dict.GetOrAdd(key, GenerateValue);

Console.WriteLine($"The value of key '{key}' is {value}");

Console.ReadLine();

}

static int GenerateValue(string key)

{

Console.WriteLine($"Generating value for key '{key}'");

// Simulate some time-consuming operation

System.Threading.Thread.Sleep(1000);

return key.GetHashCode();

}

}

在上面的示例代码中,我们创建了一个 ConcurrentDictionary 对象,并使用 GetOrAdd() 方法向字典中添加键值对。当第一个线程尝试获取键 "key1" 对应的值时,由于字典中并不存在该键,所以 valueFactoryMethod 会被调用来生成值。而当第二个线程尝试获取同样的键时,它会等待第一个线程生成完毕后直接返回生成的值。这样,valueFactoryMethod 只会被调用一次,避免了重复执行的开销。

ConcurrentDictionary.GetOrAdd() 方法确保每个键只调用一次 valueFactoryMethod,从而避免了多个线程重复执行的开销。这使得我们可以放心地在多线程环境下使用 ConcurrentDictionary 来进行并发的字典操作。