2013-07-06 35 views
1

我從多個線程調用一個簡單字符串串聯函數。我認爲應該鎖定它。用鎖或無鎖進行了許多測試。它從未失敗。是否鎖定:並行字符串串聯

我的問題是:字符串連接是否必須鎖定?

private readonly object idLock = new object(); 

private string GetId(string input1, string input2, string input3) 
{ 
    lock (idLock) 
     return string.Format("{0}; {1}; {2}", input1, input2, input3); 
} 

我用PLINQ - 10000000個週期測試了以下變體。時間以毫秒爲:

// Time 5446 
lock (idLock) 
    return string.Format("{0}; {1}; {2}", input1, input2, input3); 

// Time 3728 
lock (idLock) 
    return input1 + "; " + input2 + "; " + input3; 

// Time 953 
return string.Format("{0}; {1}; {2}", input1, input2, input3); 

// Time 652 
return input1 + "; " + input2 + "; " + input3; 

完整的測試代碼是在這裏:Test Parallel String Concatenation

回答

3

不,它不具有任何鎖定結構。

任何純方法在多線程環境中都可以正常工作。

「純」的意思是一個方法:

  • 功能始終計算給定相同的參數值(一個或多個)相同的結果的值。函數結果值不能取決於任何隱藏的信息或狀態,這些信息或狀態可能隨着程序執行的進行或程序的不同執行而改變,也可能取決於來自I/O設備的任何外部輸入。
  • 對結果的評估不會導致任何語義上可觀察的副作用或輸出,例如突變可變對象或輸出到I/O設備。

(來源:Wikipedia: Pure Function

在你的情況下,通過自身字符串連接是在多線程環境很好,不需要任何鎖定結構。但是,如果您要連接的字符串是從其他線程可以更改的字段或屬性中讀取的,則需要鎖定或類似來確保系統的穩定性,但是您的示例代碼問題,不。

+0

+1謝謝。非常有建設性的答案。我記得現在我已經閱讀過。 –

3

我的問題是:字符串連接是否必須鎖定?

不,你不需要任何鎖定。 MSDN指出System.String線程安全(以及它的方法,包括Format方法)。

這並不令人驚訝,因爲.Net字符串是不可變的,這意味着它的值在創建後無法更改。不可變類型本質上是線程安全的,因爲它們的值不能被一個線程改變,而另一個線程也訪問它。如果您的輸入參數是可變的任何其他參考類型,則可能會遇到潛在問題。