目錄
- 執行緒的幾種狀態
- 基礎執行緒
- 前臺執行緒、後臺執行緒
一、執行緒的幾種狀態
我們所說的基礎執行緒就是通過Thread類顯示建立的執行緒。可以大體瞭解一下Thread類相關的成員:
屬性:
方法:
執行緒的5個狀態:
1、建立狀態(new): 對應 Thread th= new Thread(worker) 時 ,就建立了一個新的執行緒,僅僅是新建狀態,程式還沒有執行執行緒中的程式碼~
2、就緒狀態(Runnable): 對應 th.Start()方法,新建執行緒在接收到Start()命令之後,呼叫Run()方法,具體的執行執行緒。
* 雖然呼叫了Start()方法,但是執行緒也不一定即時執行Run()方法。我們知道,多執行緒是CPU線上程之間來回切換,給出一種多執行緒的感覺。
如果資源緊張,執行緒較多,有可能在切換到當前這個執行緒前,需要等待一段時間。當CPU切換到當前這個執行緒時,在給定的時間片內執行我們的執行緒。
3、執行狀態(Running): 在切換到當前執行緒時,在CPU給定的時間片內,真正的執行執行緒。
4、 阻塞狀態(Blocked): 對應 Join()、Sleep()方法。阻塞狀態是當前執行執行緒,暫時中斷執行,讓出CUP時間片,使得其他正在等待Run()的執行緒可以真正Run()。
<1> Join()方法:將呼叫Join()方法的執行緒,加入到當前執行緒。使得當前執行緒掛起,一直到呼叫Join()方法執行緒執行完畢。
static void Main(string[] args)
{
System.Threading.Thread childThead = new System.Threading.Thread(ChildThread);
childThead.Start();
//childThead.Join();
Console.WriteLine("Main thread is end");
Console.ReadKey();
}
static void ChildThread()
{
System.Threading.Thread.Sleep(10000);
Console.WriteLine("ChildThread is end");
}
先顯示主執行緒的資訊,大約10s後,子執行緒資訊顯示,執行結果:
我們解開註釋:childThead.Join(); 這裡需要理解的是,是將子執行緒childThead加入到主執行緒中,主執行緒掛起,直到子執行緒childThread執行完畢後,主執行緒才被喚醒,繼續執行。
我們想讓誰優先執行,就讓我們希望的執行緒呼叫Join().所以以上執行的結果是,首先顯示子執行緒資訊,完畢後,主執行緒才顯示資訊。
<2>Sleep()方法:使得當前執行緒休眠掛起相應的毫秒數,到了一定的時間就會喚醒自己,繼續執行。這裡休眠的毫秒數不一定是經過這個時間點就馬上喚醒,因為CPU需要線上程間來回切換。
Thread.Sleep(0);在我們遇到長時間執行的執行緒時,執行一下,會讓CPU根據優先順序對執行緒重新排隊選擇。也許會是當前這個執行緒,或許是優先順序更高的。
<3>Suspend()這個方法不建議使用。
5、 死亡狀態(Dead): 對應 Abort()方法。讓執行緒進入死亡狀態有兩種方式:<1>程式結束後,執行緒自然就會結束。<2>執行中,丟擲異常。
Abort(),就是讓執行緒丟擲異常來終止執行緒。
二、基礎執行緒
1、建立執行緒
常用有2種方式可以讓我們顯示建立一個執行緒
public Thread(ThreadStart start); public Thread(ParameterizedThreadStart start);
引數:ThreadStart(無參無返回值委託) 和 ParameterizedThreadStart(有一個引數無返回值委託) 就是一個委託,如下:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
先建立一個與之(此例為:ThreadStart委託)對應的方法:
static void ChildThread() { System.Threading.Thread.Sleep(10000); Console.WriteLine("ChildThread is end"); }
再建立基礎執行緒:
System.Threading.Thread childThead = new System.Threading.Thread(ChildThread); childThead.Start();
三、前臺執行緒與後臺執行緒
CLR將執行緒分為兩種,即前臺執行緒和後臺執行緒。
執行緒的狀態可以從前臺和後臺,在生命週期中來回切換。
應用程式主執行緒以及通過Thread物件顯示建立的執行緒預設為前臺執行緒,執行緒池的執行緒預設為後執行緒。
例項:
System.Threading.Thread backgroundThread = new System.Threading.Thread(BackGroundThreadWorker); if (!backgroundThread.IsBackground) backgroundThread.IsBackground = true; backgroundThread.Start(); var mt = System.Threading.Thread.CurrentThread; mt.Name = "Main"; Console.WriteLine("【Main Thread】: Name—{0};IsBackground—{1};ThreadState—{2}", mt.Name, mt.IsBackground.ToString(), mt.ThreadState.ToString()); Console.WriteLine("Main thread end."); Console.WriteLine(); //主執行緒沒有結束,後臺執行緒繼續執行~~ //Console.ReadKey();
與子執行緒委託對應的方法
public static void BackGroundThreadWorker()
{
var bc = System.Threading.Thread.CurrentThread;
bc.Name = "Background";
Console.WriteLine();
Console.WriteLine("【Background Thread】:Name—{0};IsBackground—{1};ThreadState—{2}", bc.Name, bc.IsBackground.ToString(), bc.ThreadState.ToString());
System.Threading.Thread.Sleep(10000);
Console.WriteLine("Background thread end.");
}
<1>我們執行以上程式,發現主執行緒(前臺執行緒)的資訊顯示後,程式直接結束,後臺執行緒也就結束,所以不顯示資訊。
<2>解開以下注釋,使得主執行緒在等待,所以大約10s後,子執行緒資訊顯示。
//主執行緒沒有結束,後臺執行緒繼續執行~~
Console.ReadKey();