代码之家  ›  专栏  ›  技术社区  ›  Ikaso

多线程和布尔

  •  7
  • Ikaso  · 技术社区  · 16 年前

    我有一个包含如下布尔字段的类:

    public class MyClass
    {
        private bool boolVal;
        public bool BoolVal
        {
            get { return boolVal; }
            set { boolVal = value; }
        }
    }
    

    可以使用属性从多个线程读取和写入字段。我的问题是我是否应该用一个锁语句来限制getter和setter?或者我应该简单地使用volatile关键字并保存锁?或者我应该完全忽略多线程,因为获取和设置布尔值是原子的?

    当做,

    2 回复  |  直到 16 年前
        1
  •  9
  •   Lasse V. Karlsen    13 年前

    简单的第一步。是的,读写布尔变量是一个原子操作( :我的意思是读写操作 他们自己 是布尔函数的原子运算,而不是读取 写入时,当然会生成两个操作,这两个操作一起不会是原子的)

    但是,除非您采取额外的步骤,否则编译器可能会优化这些读写操作,或者移动操作,这可能会使您的代码的操作与您所期望的不同。

    将字段标记为 volatile 这意味着操作不会被优化掉,指令基本上说编译器不应该假设这个字段中的值与前一个字段中的值相同,即使它只是在前一条指令中读取它。

    但是,在多核和多CPU计算机上,不同的核和CPU在其缓存中的字段值可能不同,因此您可以添加 lock { } 子句或任何其他强制记忆障碍的内容。这将确保字段值在各个核心之间保持一致。此外,读写操作不会越过代码中的内存屏障,这意味着您可以预测操作发生的位置。

    因此,如果您怀疑或知道这个字段将被写入多个线程并从多个线程读取,我肯定会将锁定和volatile添加到混合中。

    请注意,我不是多线程方面的专家,我可以自己处理,但我通常会防御性地编程。有可能(我认为很可能)您可以实现一些不使用锁的东西(有许多无锁结构),但遗憾的是,我在这个主题中没有足够的经验来处理这些事情。因此,我的建议是在 lock 条款和a 不稳定的 指令。

        2
  •  2
  •   user90843 user90843    16 年前

    单靠volatile是不够的,它有不同的用途,lock应该是好的,但最终要看是否有人要在我的类中设置boolVal,谁知道呢,你可能有一个worker线程在里面旋转。这也取决于你如何在内部使用boolVal。你可能还需要其他地方的保护。如果你问我,如果你不确定你会在多个线程中使用MyClass,那么你甚至不值得去考虑它。

    this section

    推荐文章