【问题标题】:are class level public properties thread safe类级公共属性是线程安全的
【发布时间】:2011-06-23 06:48:53
【问题描述】:

如果 w3wp.exe 是负责满足 Web 应用程序的所有传入请求的进程(如果我错了,请纠正我),如果我有一个类,我们就这样称呼它为客户

public class Customer  
{  
  public string FirstName{get;set;}  
  public string LastName{get;set;}
}

所以现在当在这样的代码中访问这个类时

 var customer = new Customer();

在堆中创建一个实例,并且在 w3wp.exe 中运行的所有线程都可以访问客户对象的属性 FirstName 和 LastName。

那么,在这种情况下,FirstName 和 LastName 属性是否不是线程安全的?使用仅属于特定实例且线程安全的私有属性总是明智的吗?

【问题讨论】:

  • 在你的场景中两个线程是否有可能获得相同的Customer 对象?例如,来自某个共享状态或静态容器?
  • 不。这个类位于业务层,它不是静态的或共享的。因此,如果此类作为请求的一部分被实例化,则每个实例化都在新线程上运行,因此在这种情况下,类级别的公共属性是线程安全的,因为它不是静态或共享资源。有错请指正。
  • 它不一定是“新”线程,很可能是缓存线程。此缓存线程维护您的 ASP.NET 应用程序(HttpApplication 或“全局”)的一个实例。所以这个线程会带来任何可能已经存在的上下文。

标签: c# multithreading


【解决方案1】:

虽然编译器为自动属性创建了一个支持字段,但它不会在其上创建任何同步。

至于线程安全 - 这取决于您在线程中使用此类的对象做什么。如果每个线程有一个不同的对象,没问题。

如果您从多个线程访问 same 对象(即共享资源),情况会有所不同:

如果您所做的只是读取一个值,而不是从多个线程设置它,那么没有问题。

如果您从多个线程修改对象,则可能会出现问题。这需要同步,你可以在你的线程代码中添加一些东西。

【讨论】:

  • 我认为您的回答简直令人困惑。你最后说的是正确的,但不是在 OP 提出问题的背景下,我认为它甚至不相关。
【解决方案2】:

正如 Oded 指出的那样,通常没关系。但是,如果您担心线程问题,请不要让编译器为您生成支持字段,而是自己将其写出来并加上前缀volatile。应用会为此付出性能损失。

如果您真的担心线程,您可以在分配时使用this method 手动互锁它们。

我见过的最佳实践是在代码周围使用简单的lock + volatile 前缀作为我的代码中出现在多线程上下文中的变量。使用这种技术从来没有遇到过问题。

【讨论】:

  • 抱歉,您为什么要同时使用volatilelock?此外,如果您让情绪(“如果您真的很担心”)指导您的多线程编程,那么您的理解可能存在重大差距。
  • 一旦你用锁保护,volatile 是虚假的。你不知道吗?如果没有,那么你有差距。如果是这样,那么我无法理解您的答案。无论哪种方式都有问题!
【解决方案3】:

您对工作进程的工作方式没有非常清楚的概念。本质上,每个线程都会创建一个类的新实例。如此有效地,您的类不需要是线程安全的,实际上也不是线程安全的。

为了清楚起见,您对私有/公共字段和线程安全的理解根本不正确(我不相信)。所以在这种情况下,你不应该这样想它们。

在堆中创建一个实例并且 中运行的所有线程 w3wp.exe 可以访问属性 客户的名字和姓氏 对象。

不,不是所有的线程。每个线程都会得到它自己的实例。我在这里假设您已经在页面或控制器中创建了客户的实例?这样想,您的应用程序接收到的每个请求都是一个线程,因为每个请求都会创建一个页面(或控制器)的新实例,因此您在页面或控制器中创建的任何对象也特定于该线程,因此在大多数情况下,你是安全的。当然,如果您正在做一些您没有提到的事情,或者您没有在页面或控制器中创建客户对象的实例,那么在您得到答案之前,您需要回答各种其他问题/场景。

我在我的博客上写了一篇文章,解释了这一切的工作原理。这篇文章的目的有所不同,但我相信您将在那里学到的内容将帮助您更好地了解 IIS 和 Worker 进程的工作原理以及它们如何与您的 ASP.NET 应用程序交互。

ASP.NET Performance-Instantiating Business Layers

【讨论】:

  • 这在很大程度上取决于开发者是否从现有的共享源中抓取对象;也许是会话/缓存(如果在内存中),或者任何静态容器。这实际上很常见。这个答案非常具有误导性,因为它完全忽略了这种可能性。
  • 我也看到这个问题和那篇博客文章之间几乎没有关系。
  • @Marc 在文章中我谈到了 IIS/Worker Process 如何创建和缓存线程,以及它如何应用于“全局”以及您的 ASP.NET 应用程序。这部分与 OP 的混淆非常相关。我相信我们可以描绘极其复杂的情况,并且基本上用“依赖”来回答大多数问题(就像事情一样)。我只是试图保持简单,因为很明显 OP 对于编程或多线程环境(如 IIS/ASP.NET)来说都是新的。微软努力让人们不去注意 ASP.NET 中的线程(至少在刚开始时)。
  • 这些都与这个问题无关,抱歉。但事实并非如此。
  • 我想我们会让 OP 决定 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
相关资源
最近更新 更多