首先使用設計模式中的單件模式,防止多次初始化對象,造成存取空間的不一致。
計數處要加lock,將其他執行緒計數暫時阻塞,確保計數的正確性。
如果要即時計數即時輸出,可以將計數和輸出處一併lock處理,不然不同執行緒的計數和輸出結果未必依序處理,
如此加鎖保證依序處理依序輸出,不過這樣多少都損失了一些效能
程式碼中加鎖位置很重要
此程式會增加三次運算,原因是本線程未到200次,但是必然會有一個線程第一次增加所以在add裡再做判斷
複製代碼代碼如下:
CommonSigleton MyCounter =CommonSigleton.Instance;
/// <summary>
/// 執行緒工作
/// </summary>
public void DoSomeWork()
{
///建構顯示字串
string results = "";
///建立一個Sigleton實例
System.Threading.Thread.Sleep(100);
int i = 0;
while (MyCounter.GetCounter() < 200)
{
//確保計數與輸出一致,即便計數與輸出之間加上時間間隔也會為這塊區域加鎖,防止其他執行緒操作
lock (this)
{
///開始計數
MyCounter.Add();
System.Threading.Thread.Sleep(100);
Thread thread = Thread.CurrentThread;
results += "線程";
results += i++.ToString() + "――〉" + thread.Name + " ";
results += "目前的計數:";
results += MyCounter.GetCounter().ToString();
results += "/n";
Console.WriteLine(results);
// 清空顯示字串
results = "";
}
}
}
public void StartMain()
{
Thread thread0 = Thread.CurrentThread;
thread0.Name = "Thread 0";
Thread thread1 =new Thread(new ThreadStart(DoSomeWork));
thread1.Name = "Thread 1";
Thread thread2 =new Thread(new ThreadStart(DoSomeWork));
thread2.Name = "Thread 2";
Thread thread3 =new Thread(new ThreadStart(DoSomeWork));
thread3.Name = "Thread 3";
thread1.Start();
thread2.Start();
thread3.Start();
///執行緒0也只執行和其他執行緒相同的工作
DoSomeWork();
}
}