.NET多執行緒程式設計(2):System.Threading.Thread類 (轉)

worldblog發表於2007-12-14
.NET多執行緒程式設計(2):System.Threading.Thread類 (轉)[@more@]

多執行緒(2):System.Threading.Thread:namespace prefix = o ns = "urn:schemas--com::office" />

在接下來的這篇文章中,我將向大家介紹.NET中的執行緒,怎麼樣用建立執行緒,啟動和停止執行緒,設定優先順序和狀態.

在.NET中編寫的將被自動的分配一個執行緒.讓我們來看看用C#程式語言建立執行緒並且繼續學習執行緒的知識。我們都知道.NET的執行時環境的主執行緒由Main ()方法來啟動應用程式,而且.NET的編譯語言有自動的垃圾收集功能,這個垃圾收集發生在另外一個執行緒裡面,所有的這些都是後臺發生的,讓我們無法感覺到發生了什麼事情.在這裡預設的是隻有一個執行緒來完成所有的程式任務,但是正如我們在第一篇文章討論過的一樣,有可能我們根據需要自己新增更多的執行緒讓程式更好的協調工作。比如說我們的例子中,一個有輸入的同時需要繪製圖形或者完成大量的運算的程式,我們必須得增加一個執行緒,讓使用者的輸入能夠得到及時的響應,因為輸入對時間和響應的要求是緊迫的,而另外一個執行緒負責圖形繪製或者大量的運算。

.NET 基礎類庫的System.Threading名稱空間提供了大量的類和介面支援多執行緒。這個名稱空間有很多的類,我們將在這裡著重討論Thread這個類。

System.Threading.Thread類是建立並控制執行緒,設定其優先順序並獲取其狀態最為常用的類。他有很多的方法,在這裡我們將就比較常用和重要的方法做一下介紹:

Thread.Start():啟動執行緒的;

Thread.Suspend():掛起執行緒,或者如果執行緒已掛起,則不起作用;

Thread.Resume():繼續已掛起的執行緒;

Thread.Interrupt():中止處於 Wait或者Sleep或者Join 執行緒狀態的執行緒;

Thread.Join():阻塞執行緒,直到某個執行緒終止時為止

Thread.Sleep():將當前執行緒阻塞指定的毫秒數;

Thread.Abort():以開始終止此執行緒的過程。如果執行緒已經在終止,則不能透過Thread.Start()來啟動執行緒。

透過呼叫Thread.Sleep,Thread.Suspend或者Thread.Join可以暫停/阻塞執行緒。呼叫Sleep()和Suspend()方法意味著執行緒將不再得到時間。這兩種暫停執行緒的方法是有區別的,Sleep()使得執行緒立即停止執行,但是在呼叫Suspend()方法之前,公共語言執行時必須到達一個點。一個執行緒不能對另外一個執行緒呼叫Sleep()方法,但是可以呼叫Suspend()方法使得另外一個執行緒暫停執行。對已經掛起的執行緒呼叫Thread.Resume()方法會使其繼續執行。不管使用多少次Suspend()方法來阻塞一個執行緒,只需一次呼叫Resume()方法就可以使得執行緒繼續執行。已經終止的和還沒有開始執行的執行緒都不能使用掛起。Thread.Sleep(int x)使執行緒阻塞x毫秒。只有當該執行緒是被其他的執行緒透過呼叫Thread.Interrupt()或者Thread.Abort()方法,才能被喚醒。如果對處於阻塞狀態的執行緒呼叫Thread.Interrupt()方法將使執行緒狀態改變,但是會丟擲ThreadInterupptedException異常,你可以捕獲這個異常並且做出處理,也可以忽略這個異常而讓執行時終止執行緒。在一定的等待時間之內,Thread.Interrupt()和Thread.Abort()都可以立即喚醒一個執行緒。

下面我們將說明如何從一個執行緒中止另外一個執行緒。在這種情況下,我們可以透過使用Thread.Abort()方法來永久銷燬一個執行緒,而且將丟擲ThreadAbortException異常。使終結的執行緒可以捕獲到異常但是很難控制恢復,僅有的辦法是呼叫Thread.ResetAbort()來取消剛才的呼叫,而且只有當這個異常是由於被呼叫執行緒引起的異常。因此,A執行緒可以正確的使用Thread.Abort()方法作用於B執行緒,但是B執行緒卻不能呼叫Thread.ResetAbort()來取消Thread.Abort()操作。Thread.Abort()方法使得悄悄的銷燬了執行緒而且不通知使用者。一旦實施Thread.Abort()操作,該執行緒不能被重新啟動。呼叫了這個方法並不是意味著執行緒立即銷燬,因此為了確定執行緒是否被銷燬,我們可以呼叫Thread.Join()來確定其銷燬,Thread.Join()是一個阻塞呼叫,直到執行緒的確是終止了才返回。但是有可能一個執行緒呼叫Thread.Interrupt()方法來中止另外一個執行緒,而這個執行緒正在等待Thread.Join()呼叫的返回。

儘可能的不要用Suspend()方法來掛起阻塞執行緒,因為這樣很容易造成死鎖。假設你掛起了一個執行緒,而這個執行緒的資源是其他執行緒所需要的,會發生什麼後果。因此,我們儘可能的給重要性不同的執行緒以不同的優先順序,用Thread.Priority()方法來代替使用Thread.Suspend()方法。

Thread類有很多的屬性,這些重要的屬性是我們多執行緒程式設計必須得掌握的。

Thread.IsAlive屬性:獲取一個值,該值指示當前執行緒的執行狀態。如果此執行緒已啟動並且尚未正常終止或中止,則為 true;否則為 false。

Thread.Name 屬性:獲取或設定執行緒的名稱。

Thread.Priority 屬性:獲取或設定一個值,該值指示執行緒的排程優先順序。

Thread.ThreadState 屬性:獲取一個值,該值包含當前執行緒的狀態。

在下面的例子中,我們將看看怎麼設定這些屬性,在隨後的例子中我們將詳細的討論這些屬性。

建立一個執行緒,首先得例項化一個Thread類,在類得構造中呼叫ThreadStart委派。這個委派包含了執行緒從哪裡開始執行。當執行緒啟動後,Start()方法啟動一個新的執行緒。下面是例子程式。

using System;


using System.Threading ;


namespace LearnThreads


{


 


class Thread_App


{


  public static void First_Thread()


  {


  Console.WriteLine("First thread created");


  Thread current_thread = Thread.CurrentThread;


  string thread_details = "Thread Name: " + current_thread.Name +


  "rnThread State: " + current_thread.ThreadState.ToString()+


  "rn Thread Priority level:"+current_thread.Priority.ToString();


  Console.WriteLine("The details of the thread are :"+ thread_details);


  Console.WriteLine ("first thread tenated");


  }


  public static void Main()


  {


  ThreadStart thr_start_func = new ThreadStart (First_Thread);


  Console.WriteLine ("Creating the first thread ");


  Thread fThread = new Thread (thr_start_func);


  fThread.Name = "first_thread";


  fThread.Start ();  //starting the thread


  }


}


}


在這個例子中,建立了一個fThread的執行緒,這個執行緒負責執行First_Thread()方法裡面的任務。當Thread的Start() 方法被呼叫時包含First_Thread()的地址ThreadStart的將被執行。

Thread狀態

System.Threading.Thread.ThreadState屬性定義了執行時執行緒的狀態。執行緒從建立到執行緒終止,它一定處於其中某一個狀態。當執行緒被建立時,它處在Unstarted狀態,Thread類的Start() 方法將使執行緒狀態變為Running狀態,執行緒將一直處於這樣的狀態,除非我們呼叫了相應的方法使其掛起、阻塞、銷燬或者自然終止。如果執行緒被掛起,它將處於Suspended狀態,除非我們呼叫resume()方法使其重新執行,這時候執行緒將重新變為Running狀態。一旦執行緒被銷燬或者終止,執行緒處於Stopped狀態。處於這個狀態的執行緒將不復存在,正如執行緒開始啟動,執行緒將不可能回到Unstarted狀態。執行緒還有一個Background狀態,它表明執行緒執行在前臺還是後臺。在一個確定的時間,執行緒可能處於多個狀態。據例子來說,一個執行緒被呼叫了Sleep而處於阻塞,而接著另外一個執行緒呼叫Abort方法於這個阻塞的執行緒,這時候執行緒將同時處於WaitSleepJoin和AbortRequested狀態。一旦執行緒響應轉為Sle阻塞或者中止,當銷燬時會丟擲ThreadAbortException異常。

執行緒優先順序

System.Threading.Thread.Priority列舉了執行緒的優先順序別,從而決定了執行緒能夠得到多少CPU時間。高優先順序的執行緒通常會比一般優先順序的執行緒得到更多的CPU時間,如果不止一個高優先順序的執行緒,將在這些執行緒之間迴圈分配CPU時間。低優先順序的執行緒得到的CPU時間相對較少,當這裡沒有高優先順序的執行緒,作業系統將挑選下一個低優先順序 的執行緒執行。一旦低優先順序的執行緒在執行時遇到了高優先順序的執行緒,它將讓出CPU給高優先順序的執行緒。新建立的執行緒優先順序為一般優先順序,我們可以設定執行緒的優先順序別的值,如下面所示:

  • Highest
  • AboveNormal
  • Normal
  • BelowNormal
  • Lowest

結論:在這一部分,我們討論了執行緒的建立何執行緒的優先順序。System.Threading名稱空間還包含了執行緒鎖定、執行緒同步何通訊、多執行緒管理類以及死鎖解決等等高階特性,在後面的部分我們將繼續討論這些內容。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993471/,如需轉載,請註明出處,否則將追究法律責任。

相關文章