这个方法线程安全吗?

时间:2011-01-25 20:27:36

标签: c# .net multithreading

有人可以告诉我以下方法是否是线程安全的。另外,请假设对_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;
    }     

4 个答案:

答案 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()”实例。