2010-07-28 48 views
1

最近我有一個關於在數百個線程使用的類中使用靜態方法的爭議。 在我看來,「第一」解決方案沒有特別的好處,除了它更容易用於課堂的客戶,但我被告知這是一個非常糟糕的主意,我不得不使用「第二」解決方案。任何人都可以給我清楚的解釋,爲什麼我錯了? 非常感謝!使用靜態方法或實例化類?

PS 讓我們假設字典是線程安全的。

class A 
{ 
    static Dictionary<int, string> m_dic = new Dictionary<int, string>(); 
    public static string GetData1(int nKey) 
    { 
     return m_dic[nKey]; 
    } 
    public string GetData2(int nKey) 
    { 
     return m_dic[nKey]; 
    } 
} 

//these func are called from threads... 
void ThreadFunc1() 
{ 
    print A.GetData1(1); 
} 

void ThreadFunc2() 
{ 
    A a = new A(); 
    print a.GetData2(1); 
} 

問候, 列昂尼德

回答

3

如果線程需要訪問一個線程安全的共享資源,靜態類是完全可行的。所以你沒有錯。

5

使用實例成員意味着(對我來說,至少)是有相關的有關實例本身的東西 - 無論它的狀態,或可能其在重載方法方面的行爲(即「狀態」是實例的執行時間類型)。

在這種情況下,這些都不是真的 - 所以我會將視圖創建爲不良風格,導致誤導性代碼。

1

C#中的靜態數據可以與C++,Delphi和其他語言中的global variables進行比較。它們往往是壞的,因爲變量的內存是在應用程序啓動時分配的,並且只在應用程序結束時才釋放。他們被認爲是不好的,因爲他們可以從代碼中的任何位置進行修改。
當然,您使用靜態方法來訪問靜態數據,但我會建議您將靜態數據設置爲私有,所以只有類本身可以通過靜態方法修改數據。然後整個數據變成singleton
順便說一句,你認爲它是線程安全的,但你最好確保它是線程安全的。
關於通過實例調用靜態方法。如果您需要實例來完成其他任務,那麼這很有意義,否則就會造成資源浪費。這沒有錯,除非有些開發人員將方法從靜態方法更改爲非靜態方法,或者當他們添加具有相同名稱和相似參數的非靜態方法時。從實例調用靜態方法也會增加混淆,因爲它不清楚該方法對類本身中的數據沒有任何影響。

+0

>>順便說一句,你認爲它是線程安全的,但你最好確保它是線程安全的。 即時通訊使用線程保存版本 - 所以不要擔心:) – Leonid 2010-07-28 14:46:18

2

我肯定會去靜態方法的所有原因喬恩說,再加上我想補充一個。考慮在多線程環境中運行的以下代碼。

void ThreadFunc2() 
{ 
    var a = new A(); 
    if (a.GetData2(1) == "foo") 
    { 
    DoSomething(a.GetData2(1)); 
    } 
} 

不知情的程序員創建的A一個新實例,並天真地發出兩次呼叫GetData2是互相依賴的思想,由於A例如不能用於其他地方沒有什麼可能出錯。但問題是沒有保證GetData2將第二次返回相同的東西,因爲另一個線程可能已經改變了該方法使用的靜態字典。當您使用實例方法提取靜態時,這完全不明顯。

我並不是說使用實例成員來讀取靜態就一定是錯誤的。我在說的是它有潛在的引起問題,特別是當暗示可以安全地從多個線程同時使用單獨的對象實例時。

相關問題