2011-01-20 80 views

回答

4

這取決於您是否希望您的類型是線程安全的......以及您的意思。

大多數情況下,我認爲類型不是是線程安全的,但可以通過適當的同步從不同線程安全地使用是完全合理的。大多數.NET類型都屬於這個類別。

這樣你通常可以確保只有「協調」對象需要擔心同步,而不是在每個方法和屬性中放置一個鎖 - 這是一種痛苦的策略,並沒有真正解決更廣泛的同步問題無論如何,你很可能會遇到。

當然,從多個線程(特別是用於實現併發性或服務定位符等)設計的類型,應該是線程安全的,並且要有文檔記錄。同樣,完全不可變的類型自然是線程安全的。

最後,還有一個問題是什麼纔算「線程安全」開始。你應該閱讀Eric Lippert's blog post來澄清你應該考慮和記錄什麼樣的事情。

4

是的,你應該關心,因爲相同的類實例方法可以作爲回調傳遞給多個線程。例如:

var instance = new Foo(); 
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod); 
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod); 

實例方法現在需要同步,因爲在這種情況下共享狀態是實例本身。

+0

應該方法名,開始在C#中的大寫字母? – jmort253 2011-01-20 08:57:36

+0

@ jmort253,哦,是的,他們是。 – 2011-01-20 08:58:24

+0

很高興知道。謝謝。起初我沒有看到C#標籤,並且正在考慮Java命名約定。 – jmort253 2011-01-20 09:28:43

0

考慮下面的代碼:

public void Execute() 
{ 
    Task.Factory.StartNew(Iterrate); 
    Task.Factory.StartNew(Add); 
} 

private List<int> _list = Enumerable.Range(1, 10).ToList(); 

private void Iterrate() 
{ 
    foreach (var item in _list) 
    { 
     Console.WriteLine(item); 
    } 
} 

private void Add() 
{ 
    _list.Add(_list.Count); 
} 

該代碼將導致(大部分時間):

InvalidOperationException: Collection was modified; enumeration operation may not execute.