【问题标题】:are class level property or variables thread safe类级属性或变量是线程安全的
【发布时间】:2010-11-25 13:08:43
【问题描述】:

我总是让这个特定的场景让我担心万年。假设我的班级是这样的

public class Person {
public Address Address{get;set;}
public string someMethod()
{}
}

我的问题是,我的开发人员同事告诉我,Address 类型的 Address 属性不是线程安全的。

从 Web 请求的角度来看,每个请求都在单独的线程上运行,并且每次 线程在我的业务对象或代码后面处理以下行,例如

var p = new Person();

它在堆上创建一个新的 Person 对象实例,因此请求线程可以访问该实例,除非我在我的应用程序中生成多个线程。

如果我错了,请向我解释为什么我错了以及为什么公共属性(地址)不是线程安全的?

任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: multithreading thread-safety


    【解决方案1】:

    如果对您的Person 实例的引用在多个线程之间共享,则多个线程可能会更改Address,从而导致竞争条件。但是,除非您将该引用保存在静态字段或 Session(某种全局可访问的位置)中,否则您无需担心。

    如果您在代码中创建对对象的引用,如上面所示 (var p = new Person();),那么您是完全线程安全的,因为其他线程将无法访问对这些对象的引用,而无需诉诸讨厌和恶意的技巧.

    【讨论】:

    • “除非您确实在静态字段或会话中持有该引用”,或者您将对象的相同实例传递给工作线程。
    • 谢谢大家,现在真的很有意义。
    【解决方案2】:

    您的属性不是线程安全的,因为您没有锁定来防止对该属性的多次写入相互影响。

    但是,在您没有在多个线程之间共享类的实例的情况下,该属性不需要是线程安全的。

    在多个线程之间共享的对象,其中每个线程都可以更改对象的状态,那么所有的状态更改都需要受到保护,以便一次只有一个线程可以修改对象。

    【讨论】:

      【解决方案3】:

      你应该没问题,但是有一些事情我会担心......

      如果要修改您的 Person 对象或持有一些一次性资源,您可能会发现其中一个线程将无法读取此变量。为了防止这种情况,您需要在读/写之前锁定对象,以确保它不会被其他线程踩踏。最简单的方法是使用 lock{} 构造。

      【讨论】:

      • 谢谢大家,现在真的很有意义。
      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2014-06-05
      相关资源
      最近更新 更多