简体   繁体   中英

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. 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. Since Dictionary<T,U> is not thread-safe, the calls to TryGetValue and setting the dictionary by key are not thread safe.

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.

I would say it depends on what _cache.GetOrCreate doess.

But from the sound of it, it does not sound thread safe since it is accessing the same 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. 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();

Thread #1 is preempted by Thread #2

Thread #2 executes all the way up to region[cacheKey] = items = factory();

Thread #2 is preempted by Thread #1

Thread #1 executes factory()

Thread #1 is preempted by Thread #2

Thread #2 executes factory()

At this point in time you have two threads with two different instances of "factory()".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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