2011-01-10 136 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); 

是的,提供的對象是可變的。