同時避免讀寫資料
有時,你希望執行緒同時共享資料。當發生這種情況時,重要的是要了解程式碼並鎖定可能出錯的任何部分。兩個執行緒計數的簡單示例如下所示。
這是一些危險的(不正確的)程式碼:
using System.Threading;
class MainClass
{
static int count { get; set; }
static void Main()
{
for (int i = 1; i <= 2; i++)
{
var thread = new Thread(ThreadMethod);
thread.Start(i);
Thread.Sleep(500);
}
}
static void ThreadMethod(object threadNumber)
{
while (true)
{
var temp = count;
System.Console.WriteLine("Thread " + threadNumber + ": Reading the value of count.");
Thread.Sleep(1000);
count = temp + 1;
System.Console.WriteLine("Thread " + threadNumber + ": Incrementing the value of count to:" + count);
Thread.Sleep(1000);
}
}
}
你會注意到,而不是計算 1,2,3,4,5 …我們計算 1,1,2,2,3 ……
要解決這個問題,我們需要鎖定 count 的值,以便多個不同的執行緒不能同時讀取和寫入它。通過新增鎖和金鑰,我們可以防止執行緒同時訪問資料。
using System.Threading;
class MainClass
{
static int count { get; set; }
static readonly object key = new object();
static void Main()
{
for (int i = 1; i <= 2; i++)
{
var thread = new Thread(ThreadMethod);
thread.Start(i);
Thread.Sleep(500);
}
}
static void ThreadMethod(object threadNumber)
{
while (true)
{
lock (key)
{
var temp = count;
System.Console.WriteLine("Thread " + threadNumber + ": Reading the value of count.");
Thread.Sleep(1000);
count = temp + 1;
System.Console.WriteLine("Thread " + threadNumber + ": Incrementing the value of count to:" + count);
}
Thread.Sleep(1000);
}
}
}