扣响C#开发之门第二十一章
21.1 线程与进程的基本概念
(1)操作系统以进程的方式运行程序;进程不仅包含了运行程序的指令流,也包括了运行程序所需的内存,寄存器灯资源;
(2)线程就是运用程序执行的线,线程相当于是在进程中创建多条并行执行的线路(线程组成进程);
(3)同一进程的所有线程共享进程的资源;
ps:个人理解,程序软件的运行流程就相当于进程,将进程分为几条不同的线程,并行执行;
21.2 Thread 类
(1)C#中创建线程使用Thread 类,创建一个Thread对象就创建了一个线程
Thread workthread=new Thread(entryPoint);
(2)每个线程都需要一个入口函数,即创建Thread对象 时需要向其传递一个入口方法;利用委托实现, C#已经预定义ThreadStrat 委托(此委托无返回值,无参数);
public delegate void ThreadStrat(); // (ThreadStrat 无参数,无返回值)
此外也可以使用ParameterizedThreadStart委托创建线程,其定义如下
public delegate void ParameterizedThreadStart(object obj);
(3)因此创建线程步骤如下
(a)编写入口函数
(b)创建ThreadStart 委托实例,并将函数注册给该委托
(c)创建Thread 对象;
class myclass { //(1)编写入口函数 public static void my () { Console.WriteLine("线程开始"); Console.WriteLine("线程开始"); Console.WriteLine("线程开始"); } public myclass() { //(2)创建ThreadStart 委托实例,并将函数注册给该委托 ThreadStart startpoint = new ThreadStart(my); //(3)创建Thread 对象; Thread newthread = new Thread(startpoint); newthread.Start(); } }
(4)新版本的C#中可以省略 创建委托实例过程,可以将直接函数名称 因此步骤2可以省略;省略后如下;
Thread newthreadB = new Thread(my);
(5)也可以像这样使用匿名函数直接创建线程;
Thread threadC = new Thread(delegate() //也可以像这样使用匿名函数直接创建线程; { for (int i = 0; i < 100; i++) { Console.Write("C"); } });
匿名函数可以改写为lamda表达式 ( (参数)=>{函数体} “小括号=>大括号“”)
Thread A = new Thread(() => { for (int i = 0; i < 1000; i++) { Console.WriteLine("A"); } });
(6)Thread类常用方法

21.3 线程的优先级
(1) 当有多个进程同时存在时,默认情况下所有线程优先级一样,交替占用CPU,执行概率大概也一样
通过Priority 属性(其只是ThreadPriority枚举)可以设置线程的优先级,高的优先级线程占有更过的CPU时间,被执行的概率也大些
static void Main(string[] args) { Thread threadA = new Thread(delegate() { for (int i = 0; i < 100; i++) { Console.Write("A"); } }); Thread threadC = new Thread(delegate() { for (int i = 0; i < 100; i++) { Console.Write("C"); } }); threadA.Priority = ThreadPriority.Highest; //设置线程的Priority属性值; threadC.Start(); threadA.Start(); Console.ReadKey(); }
21.4 线程插入
(1)Thread 类的 Join方法(插入)可以能够将两个交替执行的线程合并为顺序执行
//23.4 线程插入 // (1)Thread 类的 Join方法(插入)可以能够将两个交替执行的线程合并为顺序执行 static void Main(string[] args) { Thread threadC = null; Thread threadA = new Thread(delegate() { threadC.Join(); //使用Join()插入线程,改变线程为顺序执行 for (int i = 0; i < 100; i++) { Console.Write("A"); } }); threadC = new Thread(delegate() { for (int i = 0; i < 100; i++) { Console.Write("C"); } }); threadA.Priority = ThreadPriority.Highest; threadA.Start(); threadC.Start(); Console.ReadKey(); }
21.5 线程的状态:
(1)线程创建后就处于 Unstarted状态,调用 Start方法后处于Running状态,
running 状态的线程调用Suspend方法 线程进入SuspendRequeested状态,然后进入Suspend状态;running 状态的线程调用Abort方法进入AbortRequested 状态,然后
收到ThreadAbortException后进入Stopped状态;
(2)有三种方法使running的线程进入 waiSleepJoin状态;
(a)保持线程间的同步而使线程处于waiSleepJoin(详细见后续线程同步)
(b)调用了Sleep方法
(c)在一个线程中调用了Join方法,当执行Join方法时候,另外一个线程执行,本线程处于waiSleepJoin状态

21.6 线程同步;
21.6.1 线程同步的概念:
两个或者多个线程共享一个资源,这种线程叫做相关线程;
多个线程共享的资源叫做临界资源
线程同步的必要性见下例,.NET提供了如下类用于用于线程同步的类:Interlocked(互锁),Monitor(管理),Mutex(互斥)
class Program { private static char buff; static void Main(string[] args) { string s = "床前明月光,疑是地上霜!!!"; Thread WriteThread = new Thread(() => { for (int i = 0; i < s.Length; i++) { buff = s[i]; Thread.Sleep(26); } } ); Thread ReadThread = new Thread(() => { for (int i = 0; i < s.Length; i++) { char c = buff; Console.Write(c); Thread.Sleep(20); } }); //WriteThread 必须写一字,ReadThread必须同时读一个字,才能正确输出,两个线程需要步调一致,这时候需要线程同步 WriteThread.Start(); ReadThread.Start(); Console.ReadKey(); } }
26.2 interlocked(互锁)
Interlocked 类控制计数器,实现线程同步;
浙公网安备 33010602011771号