Thread類有幾個至關重要的方法,描述如下:
Start():啟動線程;
Sleep(int):靜態方法,暫停當前線程指定的毫秒數;
Abort():通常使用該方法來終止一個線程;
Suspend():該方法並不終止未完成的線程,它僅僅掛起線程,以後還可恢複;
Resume():恢複被Suspend()方法掛起的線程的執行;
Join():使主線程等待,直到子線程結束。
Thread.ThreadState 屬性
這個屬性代表了線程運行時狀態,在不同的情況下有不同的值,我們有時候可以通過對該值的判斷來設計程式流程。
ThreadState 屬性的取值如下:
Aborted:線程已停止;
AbortRequested:線程的Thread.Abort()方法已被調用,但是線程還未停止;
Background:線程在後台執行,與屬性Thread.IsBackground有關;
Running:線程正在正常運行;
Stopped:線程已經被停止;
StopRequested:線程正在被要求停止;
Suspended:線程已經被掛起(此狀態下,可以通過調用Resume()方法重新運行);
SuspendRequested:線程正在要求被掛起,但是未來得及響應;
Unstarted:未調用Thread.Start()開始線程的運行;
WaitSleepJoin:線程因為調用了Wait(),Sleep()或Join()等方法處於封鎖狀態;
上面提到了 Background狀態表示該線程在後台運行,那麼後台啟動並執行線程有什麼特別的地方呢?其實後台線程跟前台線程只有一個區別,那就是後台線程不妨礙程式 的終止。一旦一個進程所有的前台線程都終止後,CLR(通用語言運行環境)將通過調用任意一個存活中的後台進程的Abort()方法來徹底終止進程。
線程的優先順序
當線程之間爭奪CPU時間時,CPU 是按照線程的優先順序給予服務的。在C#應用程式中,使用者可以設定5個不同的優先順序,由高到低分別是Highest,AboveNormal,Normal,BelowNormal,Lowest,在建立線程時如果不指定優先順序,那麼系統預設為ThreadPriority.Normal。
給一個線程指定優先順序,我們可以使用如下代碼:
//設定優先順序為最低
myThread.Priority=ThreadPriority.Lowest;
通過設定線程的優先順序,我們可以安排一些相對重要的線程優先執行,例如對使用者的響應等等。
C#提供了一個關鍵字lock,它可以把一段代碼定義為互斥段(critical section),互斥段在一個時刻內只允許一個線程進入執行,而其他線程必須等待。
Monitor類可以鎖定一個對象,一個線程只有得到這把鎖才可以對該對象進行操作。對象鎖機制保證了在可能引起混亂的情況下一個時刻只有一個線程可以訪問這個對象。
Monitor.Enter(對象);
Monitor.Exit(對象);//釋放鎖
//等待WriteToCell方法中調用Monitor.Pulse()方法
Monitor.Wait(this);線程等待
Monitor.Pulse(this)方法通知等待隊列中的第一個線程,於是該線程被轉移到預備隊列中,當對象鎖被釋放時,在預備隊列中的線程可以立即獲得對象鎖。
代碼using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Call c = new Call();
WriteCall w = new WriteCall(c, 20);
ReadCall r = new ReadCall(c, 20);
Thread thw =new Thread(new ThreadStart(w.Threadgo));
Thread thr = new Thread(new ThreadStart(r.Threadgo));
thr.Start();
thw.Start();
thr.Join();
thw.Join();
Console.Read();
}
}
public class Call
{
int count = 0;
bool IscanWrite = true;
public void Write(int n)
{
lock (this)
{
if (!IscanWrite)
{
Monitor.Wait(this);
}
count = n;
Console.WriteLine("write count={0}", count);
IscanWrite = false;
Monitor.Pulse(this);
}
}
public int Read()
{
lock (this)
{
if (IscanWrite)
{
Monitor.Wait(this);
}
Console.WriteLine("read count={0}", count);
IscanWrite = true;
Monitor.Pulse(this);
}
return count;
}
}
public class WriteCall
{
Call _call;
int _count;
public WriteCall(Call call,int count)
{
this._call = call;
this._count = count;
}
public void Threadgo()
{
for(int i=1;i<=_count;i++)
{
_call.Write(i);
}
}
}
public class ReadCall{
public ReadCall(Call call,int count)
{
this._call = call;
this._count = count;
}
Call _call;
int _count;
public void Threadgo()
{
for(int i=1;i<=_count;i++)
{
_call.Read();
}
}
}
}