多線程入門(1),volatile(C#)關鍵字
多線程應用程序,可以提高程序的響應速度,也就提高了用戶的體驗。在多用戶或者有耗時操作時,使用多線程提高程序的響應速度是不二的選擇。一個程序員不懂多線程,不是一個合格的程序員。所以,哥也要學習多線程了。
構建一個簡單的多線程程序
using System; 2
using System.Threading; 3
4
namespace CSharpConsoleTestingCodes 5
{ 6
class Program 7
{ 8
static void Main(string[] args) 9
{ 10
Worker worker = new Worker(); 11
//創建輔助線程 12
Thread td = new Thread(worker.DoWork);//new Thread(worker.DoWork())這樣編寫編譯錯誤。 13
td.Start();//開啟輔助線程并與主線程并行工作 14
Console.WriteLine("main thread starting the working thread... ..."); 15
while (!td.IsAlive) ;//等待輔助線程進入工作狀態。 16
//Thread.Sleep(1);//讓主線程Sleep 1ms,以讓輔助線程做一些工作;效果:圖1 17
for (int i = 0; i < 4; i++)//在主線程中同時進行一些工作;效果:圖2 18
Console.WriteLine("Doing some work in the main thread... ..."); 19
worker.StopWorking();//告訴輔助線程停止工作。 20
td.Join();//使用join()方法阻塞當前線程直到輔助線程退出。 21
Console.WriteLine("Main thread: the worker thread has terminated!"); 22
Console.ReadLine(); 23
} 24
} 25
class Worker 26
{ 27
private volatile bool mShouldStop=false;//volatile變量,作為是否退出DoWork()的標記,可以被輔助線程和主線程訪問 28
public void DoWork()//模擬某耗時工作,一直打印消息直到工作完成(mShouldStop被主線程改為ture)時結束。 29
{ 30
while (!mShouldStop) 31
Console.WriteLine("Doing somework in the aided thread... ... "); 32
Console.WriteLine("Quit the aided thread gracefully... ..."); 33
} 34
public void StopWorking()//結束工作,由主線程調用。 35
{ 36
this.mShouldStop = true; 37
} 38
} 39
} 40

以上就是一個簡單的多線程程序。由于注釋比較詳細就不一一講解了。
執行結果如圖(結果不會完全一樣,因為線程切換的時間和順序是不定的):
不過有幾點是要注意的:
- 創建線程時使用的代碼為 Thread td = new Thread(worker.DoWork); 而不是DoWork(),初學者容易寫為 new Thread(worker.DoWork()); 這是因為在Thread的構造函數中使用的是ThreadStart類型的委托,可以理解為C中的函數指針,傳遞給線程執行。 以后我們會發現,多線程中委托是很重要的角色。
- Worker類中的mShouldStop數據成員被聲明為了 volatile ,因為這個變量同時被主線程和輔助線程訪問和修改。以下是MSDN上的解釋:
volatile 關鍵字用于通知編譯器,將有多個線程訪問 mShouldStop 數據成員,因此它不應當對此成員的狀態做任何優化假設。有關更多信息,請參見 volatile(C# 參考)。
通過將 volatile 與 mShouldStop 數據成員一起使用,可以從多個線程安全地訪問此成員,而不需要使用正式的線程同步技術,但這僅僅是因為 mShouldStop 是 bool。這意味著只需要執行單個原子操作就能修改 mShouldStop 。但是,如果此數據成員是類、結構或數組,那么,從多個線程訪問它可能會導致間歇的數據損壞。假設有一個更改數組中的值的線程。Windows 定期中斷線程,以便允許其他線程執行,因此線程會在分配某些數組元素之后和分配其他元素之前被中斷。這意味著,數組現在有了一個程序員從不想要的狀態,因此,讀取此數組的另一個線程可能會失敗。
-
最后使用Join()方法結束輔助線程。以下是MSDN上的解釋:
還可以通過調用 Abort 來從一個線程終止另一個線程,但這會強行終止受影響的線程,而不管它是否已完成自己的任務,并且不提供清理資源的機會。此示例中顯示的技術是首選方法。
最后,Main 函數對輔助線程對象調用 Join 方法。此方法導致當前線程阻塞或等待,直到對象所表示的線程終止。因此,直到輔助線程返回后,Join 才會返回,然后自行終止
Finish Whatever U've Started !!!



浙公網安備 33010602011771號