有人可以告诉我以下方法是否是线程安全的。另外,请假设对_cache.GetOrCreate(...)的调用是线程安全的。此方法是创建或更新区域(字典)的应用程序中的唯一位置。包含此方法的类是单例,因此多个线程将访问它。
public IEnumerable<string> GetReportLookupItems<T>(string cacheKey, Func<IEnumerable<string>> factory)
{
Dictionary<string, IEnumerable<string>> region = _cache.GetOrCreate("Cache-Region:LookupItems", () => new Dictionary<string, IEnumerable<string>>());
IEnumerable<string> items;
if (!region.TryGetValue(cacheKey, out items))
{
region[cacheKey] = items = factory();
}
return items;
}
答案 0 :(得分:5)
没有。它绝对不是线程安全的。
您在这里使用Dictionary<T,U>
并更改其内容。由于Dictionary<T,U>
不是线程安全的,因此调用TryGetValue
并按键设置字典不是线程安全的。
如果您要将其更改为使用线程安全字典(例如ConcurrentDictionary<T,U>
),则可能会将此作为一种线程安全方法。
答案 1 :(得分:1)
我想说这取决于_cache.GetOrCreate
doess。
但是从它的声音来看,它听起来不是线程安全的,因为它访问的是同一个Dictionary
。
答案 2 :(得分:1)
不,此代码不是线程安全的,因为在共享字典(由TryGetValue
返回)上调用实例方法_cache.GetOrCreate
不是线程安全的。多个线程可能同时在同一个字典实例上调用此实例方法。
答案 3 :(得分:1)
它不是线程安全的。
线程#1一直执行到区域[cacheKey] = items = factory();
线程#1被线程#2抢占
线程#2一直执行到区域[cacheKey] = items = factory();
线程#2被线程#1抢占
线程#1执行factory()
线程#1被线程#2抢占
线程#2执行factory()
此时您有两个线程,其中包含两个不同的“factory()”实例。