难道这个例子线程安全的? [英] Is this example thread safe?

查看:104
本文介绍了难道这个例子线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有充当数据缓存单例类。多个线程会从缓存中读取,和一个单独的线程会定期刷新。它看起来是这样的:

Suppose I have singleton class that acts as a data cache. Multiple threads will read from the cache, and a single thread will periodically refresh it. It looks something like this:

public sealed class DataStore
{
    public static DataStore Instance { get { return _instance; } }
    public Dictionary<Foo, Bar> FooBar { get; private set; }

    static DataStore() { }
    private DataStore() { }

    public void Refresh() {
        FooBar = GetFooBarFromDB();
    }

    private static readonly DataStore _instance = new DataStore();
}

我的问题是本质,是安全的刷新()其他线程可以访问 FooBar的?我是否需要使用锁,或者是我的获取和设置操作原子?我是否需要显式声明挥发性字段来备份我的属性?

My question is essentially, is it safe to Refresh() while other threads may be accessing FooBar? Do I need to be using locks, or are my getting and setting operations atomic? Do I need to explicitly declare volatile fields to back up my properties?

PS,如果有人能想出一个更具描述性的标题为这个问题,我会很乐意欢迎。

P.S., If someone can think of a more descriptive title for this question, I would gladly welcome it.

编辑:固定我的例子来纠正显然非原子code

Fixed my example to correct obviously non-atomic code.

推荐答案

是的,在这样的你需要显式同步,因为另一个线程可以得到的情况下 FooBar的,并开始阅读之前你已经完成写作。

Yes, in cases like that you need explicit synchronization, because another thread could get FooBar and start reading it before you have finished writing.

如果你这样做,但是,

public void Refresh() {
    var tmp = new Dictionary<Foo, Bar>();
    // Fill out FooBar from DB
    FooBar = tmp;
}

那么你就不会需要增加显式同步,因为从一个引用到其他参考开关是原子的。

then you wouldn't need to add explicit synchronization, because the switch from one reference over to the other reference is atomic.

当然,有一个隐含的假设,在这里,还有就是刷新方法之外没有写。

Of course there is an implicit assumption here that there is no writing outside the Refresh method.

编辑:您还应该从一个自动实现的属性切换到手动实现的属性与挥发性修饰符声明后盾变量

You also should switch from an auto-implemented property to a manually implemented property with a backing variable declared with volatile modifier.

这篇关于难道这个例子线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆