2011-01-10 155 views
2

我学习C#和我感到困惑与类实例的副本线程安全的,如下:C#线程安全

eg: 
    classA objA; 
    classA objB = objA; 

    objA.field1 = value2; //do I need lock around modification of field1? 

    //let say we pass the objB to another thread 
    objB.field1 = value1 //do I need a lock for objB because of the modification of field1? 

我很困惑,因为从C的背景来++中, C#中的类是引用类型。如果objA和objB都指向相同的内存底层,那么我需要一个锁来保护同时写入field1。有人可以证实这一点,或者我错过了什么吗?

谢谢。

回答

0

这取决于。根据specification以下类型是原子的:
bool, char, byte, sbyte, short, ushort, uint, int, float,和引用类型。

如果field1是其中的一个或引用,那么如果没有其他依赖关系,则不需要锁定。

+0

原子性和线程安全通常是两个不同的问题。但我不是一个C#大师... – Guillaume 2011-01-10 09:47:37

1

你提到你的C++背景,因此也许你能想到的C#代码,因为这C++代码:

classA objA; 
classA &objB = objA; //note reference 

objA.field1 = value2; //do I need lock around modification of field1? 
         //Answer : yes if someone else has access to the object 

如果修改/多线程突变,您应该锁定对象。这可以使用财产而非公共领域轻松完成。或者使用一个简单的方法。

修改基元类型时可能有时不需要锁定。但是对于并发访问/变异的大多数情况,锁定是最简单和最安全的解决方案。

//let say we pass the objB to another thread 
//do I need a lock for objB because of the modification of field1? 
Thread newThread = new Thread((classB b) => b.field1 = value1); 

是的,提供的对象是可变的。