ConcurrentDictionary.GetOrAdd() 是否保证每个键仅调用一次 valueFactoryMethod?
ConcurrentDictionary.GetOrAdd() 是 .NET 平台提供的一种线程安全的字典实现,它允许同时访问和修改字典的操作。当我们使用 GetOrAdd() 方法向字典中添加键值对时,我们可能会想知道是否保证每个键仅调用一次 valueFactoryMethod。答案是,ConcurrentDictionary.GetOrAdd() 方法确保每个键只调用一次 valueFactoryMethod。这意味着如果多个线程同时尝试访问同一个键,只有一个线程会调用 valueFactoryMethod 来生成对应的值,并将其添加到字典中。其他线程将等待该值生成完毕后直接返回。这样可以避免多个线程重复执行 valueFactoryMethod 的开销。示例代码:csharpusing 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 来进行并发的字典操作。