2012-06-08 187 views
4

如果我有一個數組可以/將在任何給定的時間點被多個線程訪問,究竟是什麼導致它是非線程安全的,以及確保採取哪些步驟來確保在大多數情況下該數組將是線程安全的?線程安全訪問數組和線程安全訪問

我已經在互聯網上發現了很多東西,並且幾乎沒有發現關於這個主題的任何信息,似乎一切都是特定的場景(例如,這個數組是通過這兩個線程進行線程安全訪問的,在和之上)。我真的很想有人能夠回答我列在頂部的問題,或者如果有人能夠指出一個解釋所述項目的好文件。

編輯: 在環視MSDN後,我找到了ArrayList類。當您使用同步方法時,它會爲給定列表返回一個線程安全的封裝器。在列表中設置數據時(即list1 [someNumber] = anotherNumber;)包裝器會自動處理鎖定列表,還是需要鎖定它?

+0

什麼 「線程安全」 的真正含義取決於具體情況。你想防止什麼樣的「問題」? – harold

+2

Albahari關於c#中線程相關問題的着作很好:http://www.albahari.com/threading/part2.aspx#_Thread_Safety – hatchet

回答

6

當兩個線程正在訪問完全相同的資源(例如,不是本地副本,但實際上是相同資源的相同副本)時,會發生許多事情。在最明顯的情況下,如果線程#1正在訪問資源,線程#2會在中途讀取中更改它,則會發生一些不可預知的行爲。即使像一個整數這樣簡單的東西,你也可能會出現邏輯錯誤,所以試着想象一下由於不恰當地使用更復雜的東西而導致的恐怖,比如聲明爲靜態的數據庫訪問類。

處理此問題的經典方法是對敏感資源進行鎖定,以便一次只能有一個線程使用它。所以在上面的例子中,線程#1會向資源請求一個鎖並授予它,然後進入讀取它需要讀取的內容。線程#2會在中間讀取並請求鎖定資源,但被拒絕並被要求等待,因爲線程1正在使用它。當線程#1完成時,它釋放鎖定,並且對於線程#2繼續進行是可以的。

還有其他的情況,但這說明了最基本的問題和解決方案之一。在C#中,您可以:

1)使用了由框架管理的可上鎖的(如特定的.NET對象蠍子王子的link to SynchronizedCollection

2)使用[MethodImpl(MethodImplOptions.Synchronized)]來決定了,做一些危險的具體方法只能由一個線程在同一時間

3)使用lock statement隔離的特定代碼行正在做一些有潛在危險的

什麼方法最好是真的給你的情況下使用。即時不能保證 - - 作爲System.Array實現ICollection接口,該接口定義了一些同步方法來支持同步機制,如果它被命名爲publicstatic關鍵字

2

C#3.0和以上提供稱爲SynchronizedCollection其中一個通用集合類「提供了線程安全集合,其中包含由所述通用參數作爲要素所指定的類型的對象。」

4

如果我能/會被多個線程在 在任何給定時間點訪問數組,到底是什麼導致它是非線程安全的, 以及什麼是採取以確保步驟在大多數情況下,數組將是 線程安全嗎?

一般而言,數組不是線程安全的事實是兩個或多個線程可能正在修改數組內容的概念,如果您不同步對數組的訪問。

一般來說,例如,假設你有螺紋1做好這項工作:

for (int i = 0; i < array.Length; i++) 
{ 
    array[i] = "Hello"; 
} 

和線程2做這項工作(同一共享陣列上)

for (int i = 0; i < array.Length; i++) 
{ 
    array[i] = "Goodbye"; 
} 

有ISN」同步線程的任何事情,所以你的結果將取決於哪個線程首先贏得比賽。它可以是「你好」或「再見」,按照某種隨機順序,但總是至少是'你好'或'再見'。

實際寫字符串「你好」或「再見」的由CLR保證是原子。也就是說,寫入'Hello'值不能被試圖寫入'Goodbye'的線程打斷。一個必須發生在另一個之前或之後,從不在兩者之間。

因此,您需要創建某種同步機制來防止數組彼此踩在一起。您可以通過在C#中使用lock語句來完成此操作。

0

陣列是線程安全的。

但是,編碼枚舉數組的項目是不安全的,開發人員應該執行lock語句以確保在數組枚舉過程中不會更改數組。

EX:

Array arrThreadSafe = new string[] {"We", "are", "safe"}; 
lock(arrThreadSafe.SyncRoot) 
{ 
    foreach (string item in arrThreadSafe) 
    { 
    Console.WriteLine(item); 
    } 
}