在这种情况下需要锁吗?

时间:2010-01-11 16:01:10

标签: c# multithreading locking

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

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 个答案:

答案 0 :(得分:10)

原子很少。

我通常希望获得变量的最新值,而不是潜在地看到变量 - 因此需要某种内存屏障,无论是读写还是写入。锁定是实现这一目标的一种简单方法,代价是由于争用而可能会丢失一些性能。

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

答案 1 :(得分:7)

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

这一切都取决于多个线程是否可以访问该属性。而一些变量据说是原子操作,在这种原子操作的情况下,不需要使用锁。抱歉英语不好。

在你的情况下,不可变,我认为没有必要锁定。