简体   繁体   English

此方法是线程安全的吗?

[英]Is this Method Thread-Safe?

Can someone please tell me if the following method is thread safe. 有人可以告诉我以下方法是否线程安全。 Also, please assume the call to _cache.GetOrCreate(...) is thread-safe. 另外,请假定对_cache.GetOrCreate(...)的调用是线程安全的。 This method is the ONLY place in the application that creates or updates the region (dictionary). 此方法仅在创建或更新区域(词典)的应用程序中。 The class containing this method is a singleton, so multiple threads will access it. 包含此方法的类为单例,因此多个线程将访问它。

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

No. It's definitely not thread safe. 不。绝对不是线程安全的。

You're using a Dictionary<T,U> here, and changing its contents. 您在此处使用Dictionary<T,U>并更改其内容。 Since Dictionary<T,U> is not thread-safe, the calls to TryGetValue and setting the dictionary by key are not thread safe. 由于Dictionary<T,U>不是线程安全的,因此对TryGetValue的调用和通过键设置字典的操作不是线程安全的。

If you were to change this to use a thread-safe dictionary (such as ConcurrentDictionary<T,U> ), you could potentially have this be a thread-safe method. 如果将其更改为使用线程安全的字典(例如ConcurrentDictionary<T,U> ),则可能使它成为线程安全的方法。

I would say it depends on what _cache.GetOrCreate doess. 我会说这取决于_cache.GetOrCreate所做的事情。

But from the sound of it, it does not sound thread safe since it is accessing the same Dictionary . 但是从它的声音来看,由于它正在访问同一Dictionary ,因此它听起来不是线程安全的。

No, this code is not thread safe because calling the instance method TryGetValue on a shared dictionary (returned by _cache.GetOrCreate ) is not thread safe. 不,此代码不是线程安全的,因为在共享字典上调用实例方法TryGetValue (由_cache.GetOrCreate返回)不是线程安全的。 Multiple threads could potentially invoke this instance method on the same dictionary instance at the same time. 多个线程可能同时在同一字典实例上调用此实例方法。

It is not thread safe. 它不是线程安全的。

Thread #1 executes all the way up to region[cacheKey] = items = factory(); 线程1一直执行到region [cacheKey] = items = factory();。

Thread #1 is preempted by Thread #2 线程#2抢占了线程#1

Thread #2 executes all the way up to region[cacheKey] = items = factory(); 线程2一直执行到region [cacheKey] = items = factory();。

Thread #2 is preempted by Thread #1 线程#1被线程#1抢占

Thread #1 executes factory() 线程#1执行factory()

Thread #1 is preempted by Thread #2 线程#2抢占了线程#1

Thread #2 executes factory() 线程#2执行factory()

At this point in time you have two threads with two different instances of "factory()". 在这一点上,您有两个线程带有“ factory()”的两个不同实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM