代码之家  ›  专栏  ›  技术社区  ›  Tommy Carlier

这种情况下需要锁吗?

  •  11
  • Tommy Carlier  · 技术社区  · 15 年前

    是否有必要保护对多线程应用程序中引用类型的单个变量的访问?我目前锁定的变量如下:

    private readonly object _lock = new object();
    private MyType _value;
    public MyType Value
    {
      get { lock (_lock) return _value; }
      set { lock (_lock) _value = value; }
    }
    

    但我想知道这是否真的有必要?给字段赋值不是原子的吗?如果我不锁在这个箱子里会出什么问题吗?

    p.s.:mytype是一个不可变的类:所有字段都在构造函数中设置,并且不会更改。要更改某些内容,将创建一个新实例并将其分配给上面的变量。

    4 回复  |  直到 15 年前
        1
  •  10
  •   Jon Skeet    15 年前

    原子性是不够的。

    我通常希望得到一个变量的最新值,而不是潜在地看到一个过时的值——所以需要某种类型的内存屏障,无论是读还是写。锁是一种很简单的方法来实现这一点,代价是由于争用可能会损失一些性能。

    习惯于 相信在这种情况下,使变量波动就足够了。我不再相信这是事实。基本上,我现在尽量避免在涉及共享数据时编写无锁代码,除非我能够使用由真正了解这些内容的人(如Joe Duffy)编写的构建基块。

        2
  •  7
  •   ewernli    15 年前

    这里有 volatile 关键字。没有它是否安全取决于场景。但是编译器可以做到 funny stuff 如重组操作顺序。因此,即使对一个字段进行读/写也可能是不安全的。

        3
  •  4
  •   Craig Stuntz    15 年前

    这可能是个问题。这不仅仅是你必须关注的任务本身。由于缓存,如果不锁定,并发线程可能会看到对象的旧版本。因此,是否需要锁将取决于您如何使用它,而您没有显示这一点。

    这里有一个 free, sample chapter of "Concurrent Programming in Windows" 这就详细解释了这个问题。

        4
  •  0
  •   Benny    15 年前

    这完全取决于属性是否将被多个线程访问。有些变量被称为原子操作,在这种原子操作的情况下,不需要使用锁。抱歉英语不好。

    在您的情况下,不可变,我认为锁是不必要的。