【问题标题】:Why is volatile variable usually private?为什么 volatile 变量通常是私有的?
【发布时间】:2011-06-19 17:38:46
【问题描述】:

我有两个类 - 类“MyDerived”派生自抽象基类“MyBase”。同样PrimaryDerivedClass 也继承MyBase。 我首先创建PrimaryDerivedClass 的实例,然后创建'MyDerived' 的实例。

MyBase 有一个称为ProcessThread 的受保护方法,当创建PrimaryDerivedClassMyDerived 的新实例时,它的使用类似于ThreadPool.QueueUserWorkItem(ProcessThread)。现在,当我想在某些情况下停止所有线程时,我将一些布尔 volatile 变量设置为 TRUE,并且当任何其他线程找到 volatile 变量的值 = TRUE 时,它会停止处理。

当我在 MyBase 中声明“private volatile bool stopThreads”时,我没有得到预期的行为。但是,当我做到staticpublic 时,我可以看到我想要实现的目标。 如果是 private volatile 会有什么问题?

抛开上述要求,我还有一个问题: 通常,我看到 volatile 变量被声明为私有的。是否有任何重要的方面通常被宣布为私有?

(我是多线程新手。)

【问题讨论】:

标签: c# multithreading volatile


【解决方案1】:

不将访问修饰符从 private 更改为 public 不会对 volatile 字段的行为产生任何影响(至少不是易失性)。您还有其他问题,如果没有看到您的代码,我们无法猜测。

调试多线程很困难,因为代码的执行方式是不确定的 - 您无法准确预测线程何时运行。

volatile 字段是私有的事实是它们被类用于内部同步。它们是它的实现的一部分,而不是它的接口。

【讨论】:

  • 我同意你的看法。当 volatile 字段变为静态(不将其更改为公共)时,它按预期工作。是否有意义?无论如何,为什么 volatile 变量通常保持私有?
  • @CSharpLearning 等等,让我看看这里我认为您有多个 MyDerived 类的实例。当您设置 stopThreads 时,您是在您创建的每个实例上设置它还是只设置一次。如果 stopThreads 是非静态的,则该类的每个实例都有自己的副本 - 设置 stopThreads 只会影响该实例。将 stopThreads 更改为 static 会使类的所有实例共享相同的字段 - 因此只有一个共享副本需要设置。如果是这种情况,您发出的问题与多线程和可变无关。
【解决方案2】:

易失性字段是私有的,因为它们是字段,而不是易失性。如果您需要公开值,请使用属性,它允许您隐藏实现细节。

在这种情况下,您可能会将volatile Boolean 更改为ManualResetEvent,而无需更改任何调用obj.StopThreads = true 的代码。有人可能会争辩说,一个名为 Stop() 的方法会比一个属性更好。

【讨论】:

    【解决方案3】:

    这种“奇怪”的行为仅仅是因为访问修饰符。私有意味着这个变量只能从定义它的类访问。所有派生类都不能访问它,所以当你改变基类的 volatile 变量的值时,它会改变 基类内部只工作 .

    所有从基类继承的类都应该有自己的 stop-right-now 实现。但是,当您将此变量设置为公共(这意味着没有访问限制,它可以从任何地方访问)或静态(这意味着所有实例的值都是相同的,因为它“不属于”实例而是属于类并且可以访问时,一切都会发生变化按类名而不是实例)。如果您希望衍生变量可以访问您的变量,则应将其标记为受保护。

    http://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx - 这篇文章展示了访问修饰符的含义。

    【讨论】: