2012-01-25 31 views
2

我是一個.NET和Java開發人員,他對線程相對比較陌生。我想知道爲什麼靜態字段,靜態構造函數等通常被認爲是「線程安全」。爲什麼靜態字段通常被認爲是線程安全的?

例如,在.NET中構建單例時,使其成爲線程安全的技巧之一是使模式的某些組件成爲靜態。

請讓我知道,如果我上面的任何假設是不正確的。

+12

你從哪裏讀到,使靜態的東西使它線程安全? –

+0

有點相關帖子http://stackoverflow.com/q/1090650/758280。 – Jeffrey

+0

我不知道C#和.net,但在Java靜態字段不比任何其他類型的字段線程安全。 – yurib

回答

10

我想你感到困惑,這些「技巧」不是關於線程,而是避免線程初始化。因此,如果應用程序加載時啓動了某些內容,則不必擔心線程在第一次請求資源時必須初始化事件,從而避免線程首先到達那裏的競爭狀態

3

您上面的假設不正確。靜態字段不會比其他字段更加線程安全。

即使在創建單例時,指示對象的標誌/指針/項目已經構建,如果有可能同時被多個線程調用,則必須由同步原語保護。

您對單例使用靜態(類級別)變量的原因是因爲您只需要該類的一個對象。使用對象級變量會限制你每一個目標對象而不是每一個類的對象,每個對象一個對象,那麼,只是一個普通的對象:-)

1

靜態構造函數(大部分)是線程安全的,因爲運行時在運行它們之前需要鎖定,從而提供同步。不過,重入仍然是一個問題。

就「靜態領域一般被認爲是線程安全的」而言,我只能提出一般智慧來自少數白癡,因爲他們無法找到一份專業開發人員的工作而找到工作,現在通過了那對於一羣從未有機會更好地學習的學生來說是白癡。

+0

什麼是線程安全的'class fff public static readonly int five = 5; }'? –

+0

@Royi:這是更安全的線程,因爲它是'readonly',不是因爲它是'static'。 (但看到我的評論克里斯的答案,即使你的例子是不完美的線程安全) –

+0

刪除只讀會使它不安全?你說的是一個線程可以在初始化之前看到默認值嗎? –

1

靜態字段本質上不是線程安全的 - 這是一個謬誤。靜態與真正的線程無關。這隻意味着該字段與類型相關聯,而不是類型的實例。需要注意對於靜態線程安全的唯一的事情是,他們通常由靜態構造函數設置,並且通常是隻讀的例如爲:

class Foo { 
    // You can safely read `five` from any thread 
    public static readonly int five = 5; 
} 

這不會使物體本身在線程但是任何方式。關於這個集合沒有什麼線程安全的:

class Foo { 
    // You still need to take a lock before writing to this list and probably while reading from it 
    public static readonly List<Int> myList = new List<Int>; 
} 
+0

那麼,即使是隻讀類型的字段也不能保證線程安全。 –

+0

不,只是意味着一旦它被設置,沒有其他人會寫入它,所以你不能得到它的「髒讀」 –

+0

當然可以。如果構造函數啓動一個線程,或者將'this'存儲在另一個線程可以讀取的地方,然後分配該字段。 –

相關問題