基礎(chǔ)知識(shí):
線程與線程對(duì)象
多線程程序在忙于處理數(shù)據(jù)的時(shí)候仍然能響應(yīng)用戶操作。
線程是操作系統(tǒng)分配CPU的基本單元,操作系統(tǒng)會(huì)使用調(diào)度算法把多個(gè)線程分給多個(gè)核心來執(zhí)行
程序可以把分割出來的工作封裝成一個(gè)函數(shù),由線程負(fù)責(zé)執(zhí)行
每一個(gè)線程一定對(duì)應(yīng)著一個(gè)線程函數(shù),線程的運(yùn)行過程與線程函數(shù)執(zhí)行過程一一對(duì)應(yīng)
Public Thread(ThreadStart start);
線程函數(shù)的要求:必須要返回void
Thread th1=new Thread(func);
線程對(duì)象創(chuàng)建之后調(diào)用Start方法開始,代碼執(zhí)行完畢之后線程結(jié)束
程序啟動(dòng)的第一個(gè)線程稱為主線程,主線程會(huì)負(fù)責(zé)啟動(dòng)其他的線程
在線程函數(shù)中使用Thread.CurrentThread可以獲取負(fù)責(zé)執(zhí)行此函數(shù)的線程對(duì)象引用
每個(gè)線程都有一個(gè)ID,線程對(duì)象的ManagedThreadID屬性保存了這個(gè)值
線程暫?!?code>Thread.Sleep(Time);
Thread.SpinSleep(Time)可以讓CPU空轉(zhuǎn),但是線程狀態(tài)不改變
Abort方法可以提前終止線程——注意,需要加上異常捕獲結(jié)構(gòu),捕獲ThreadAbout異常,Thread.ResetAbort();
實(shí)際開發(fā)中一般不用Abort提前終止線程
背景線程
IsBackground屬性:
當(dāng)主線程結(jié)束的時(shí)候,背景線程自動(dòng)終止
默認(rèn)創(chuàng)建的都是前臺(tái)線程,CLR會(huì)等到所有前臺(tái)線程都結(jié)束的時(shí)候才會(huì)結(jié)束整個(gè)進(jìn)程
Thread類的Join方法可以讓一個(gè)線程等待另一個(gè)線程結(jié)束(線程同步)
Th.Start();
Th.Join();
相當(dāng)于把B的流程“嵌入”到A里
注意如果使用不當(dāng)容易造成死鎖
dotNet的線程屬于“托管線程”,由CLR進(jìn)行調(diào)度(操作系統(tǒng)直接調(diào)度的線程稱為物理線程)
dotNet提供的線程狀態(tài)比操作系統(tǒng)線程狀態(tài)多
輔助線程狀態(tài)切換:
Unstart
Running
Stopped
代碼演示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Chap4_1_Thread
{
public class MyClass
{
public static void StaticMethod()
{
Console.WriteLine("線程{0}執(zhí)行MyClass.StaticMethod", Thread.CurrentThread.ManagedThreadId);
}
public void InstanceMethod()
{
Console.WriteLine("線程{0}執(zhí)行MyClass.InstanceMethod", Thread.CurrentThread.ManagedThreadId);
}
}
class Program
{
static void ThreadAMethod()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("輔助線程正在執(zhí)行:" + i.ToString());
Thread.Sleep(200);
}
Console.WriteLine("輔助線程執(zhí)行結(jié)束");
}
static void Main(string[] args)
{
Console.WriteLine("main thread ID:{0}", Thread.CurrentThread.ManagedThreadId);
MyClass obj = new MyClass();
Thread th1 = new Thread(new ThreadStart(MyClass.StaticMethod));
Thread th2 = new Thread(new ThreadStart(obj.InstanceMethod));
//ThreadStart是一個(gè)委托
Thread th3 = new Thread(MyClass.StaticMethod);
//簡(jiǎn)化寫法
th1.Start();
th2.Start();
th3.Start();
//用Start方法開始執(zhí)行線程
Console.WriteLine("主線程{0}任務(wù)執(zhí)行完畢,敲任意鍵退出", Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
//以下為線程的睡眠
Thread sleeper = new Thread(()=>{
for (int i = 0; i <10; i++)
{
Thread.Sleep(100);
Console.WriteLine("第{0}次睡眠", i);
}
});
sleeper.Start();
Console.WriteLine("睡眠結(jié)束");//注意主線程和sleeper是并行運(yùn)行的
Console.ReadKey();
//使用join方法讓主線程等待子線程
Console.WriteLine("join方法演示");
Thread waiting = new Thread(ThreadAMethod);
waiting.Start();
waiting.Join();
Console.WriteLine("主線程結(jié)束");
Console.ReadKey();
//線程狀態(tài)
Console.WriteLine("顯示線程狀態(tài)");
Thread status = new Thread(() =>
{
Console.WriteLine(Thread.CurrentThread.ThreadState);
});
Console.WriteLine(status.ThreadState);
status.Start();
status.Join();
Console.WriteLine(status.ThreadState);
Console.ReadKey();
}
}
}