【问题标题】:is it thread safe to assign a new value to a static object in c#在c#中为静态对象分配新值是否线程安全
【发布时间】:2013-08-16 20:46:16
【问题描述】:

拿下面的代码,多线程环境下会发生什么:

static Dictionary<string,string> _events = new Dictionary<string,string>();

public static Dictionary<string,string> Events { get { return _events;} }

public static void ResetDictionary()
{
    _events = new Dictionary<string,string>();
}

在多线程环境中,不同线程可以同时访问此方法和属性。

将新对象分配给可在不同线程中访问的静态变量是否线程安全?会出现什么问题?

是否有时间事件可以为空?如果 2 个线程同时调用 EventsResetDictionary()

【问题讨论】:

  • 如果两个线程同时调用EventsResetDictionary,那么可能会发生:线程1 对EventsEvents 执行某些操作,最终成为一个空字典,线程 2 首先调用 ResetDictionary,然后线程 2 对其进行处理。Events 不会最终成为 null,除非它被专门设置为 null另一个线程;当一个线程在另一个线程调用ResetDictionary 之前检查Events != null 时,这可能会导致空指针异常。
  • 在您期望变量值不会改变的地方使用静态变量(每个请求都类似),或者即使改变它也不会影响您的应用程序(但它会影响。),您的应用程序有可能会在错误的逻辑上运行,它甚至不会引发任何异常,考虑用户更改任何值,然后每个其他传入请求都处理错误的数据,直到该值被其他逻辑重置。所以要明智地使用静态变量。

标签: c# thread-safety


【解决方案1】:

将新对象分配给可在不同线程中访问的静态变量是否线程安全?

基本上,是的。从某种意义上说,该属性永远不会无效或null

会出什么问题?

在另一个线程重置旧字典后,一个阅读线程可以继续使用旧字典。这有多糟糕完全取决于您的程序逻辑和要求。

【讨论】:

    【解决方案2】:

    如果您想控制多线程环境中的所有内容,则必须使用所有线程都可以访问的标志并控制您在字典中使用的方法!

    // the dictionary
    static Dictionary<string, string> _events = new Dictionary<string, string>();
    
    // public boolean
    static bool isIdle = true;
    
    // metod that a thread calls
    bool doSomthingToDictionary()
    {
        // if another thread is using this method do nothing,
        // just return false. (the thread will get false and try another time!)
        if (!isIdle) return false;
    
        // if it is Idle then:
        isIdle = false;
        ResetDictionary(); // do anything to your dictionary here
        isIdle = true;
        return true;
    }
    

    另一件事!您可以使用 Invoke 方法确保当一个线程在另一个线程中操作变量或调用函数时,其他线程不会!见链接: Cleanest Way to Invoke Cross-Thread Events

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多