1第九章多线程什么是多线程使用多线程线程的生命周期线程的优先级线程同步线程死锁2前面我们开发的程序大多是单线程的,即一个程序只有一个执行线索。然而在很多情况下需要同时执行多条线索。如Windows中,拷贝文件时显示一个文件传输的动画。使用多线程就可以解决该问题。39.1什么是多线程一、程序、进程和线程程序:一段静态的代码。进程:程序的一次动态执行过程。线程:程序内部的控制流,比进程更小的执行单位。一个进程在执行过程中,为了同时完成多个操作,可以产生多个线程,形成多条执行线索。4进程和线程的区别:(1)每个进程有一段专有内存空间,内存消耗很大,不同进程之间切换时系统开销很大,进程之间通信速度很慢。(2)同一进程的各线程之间共享相同内存空间,利用共享内存来实现数据交换、实时通信及必要的同步工作。线程之间通信速度快,相互切换所占系统资源也小。5线程的并发:两个或多个线程在一个时间段内同时运行,但某个时刻,只有一个线程在运行。线程的并行:两个或多个线程真正的同时运行在不同的CPU上。多线程指单个程序包含同时执行的多个线程。一个线程的执行不必等待另一个线程执行完才执行。当多线程程序执行时,该程序对应的进程中就有多个控制流在同时运行。两个线程程序6该女士在同时吃苹果、看书并在电脑上工作。7注意:程序运行时,首先要进行一系列初始操作,然后启动一个单线程运行Main函数,这个线程就是主线程。主线程中可以启动其他线程。.NET支持多线程System.Threading.Thread89.2使用多线程(1)先创建一个Thread对象并与某一方法对应,该方法中的代码就是将来的线程要执行的代码。(2)调用该Thread对象的Start方法即可启动线程。9classTest{publicstaticvoidFun(){System.Console.WriteLine(子线程启动);}publicstaticvoidMain(){System.Console.WriteLine(主线程启动);Threadt=newThread(Test.Fun);t.Start();System.Console.WriteLine(“主线程启动了子线程);System.Console.Read();}}10线程的睡眠Thread.Sleep(1000);//线程睡眠1秒教材例14.311线程的终止线程对象.Abort();例1210.5在Windows窗口程序中使用多线程点击开始按钮后,小球下落;点击停止按钮后,小球停止运动。13如果试图在某线程中控制其他线程中创建的控件,将会报InvalidOperationException异常。解决办法,将窗体类的CheckForIllegalCrossThreadCalls属性的值设置为false149.3线程的生命周期线程从创建到结束共分为5个状态,一个线程在其生命周期中,总是处于某种状态。初始状态、就绪状态、阻塞状态、运行状态、死亡状态。(1)初始状态线程刚被创建时,处于初始状态。例如通过如下语句创建一个名为t1的线程对象。Threadt1=newThread(方法名);此时该线程处于初始状态,还没有运行。(2)就绪状态线程被启动时,进入就绪状态。例如下列语句使线程对象t1进入就绪状态。t1.Start();在该状态中,线程已进入线程队列,接受处理机的调度。15(3)运行状态对于处于就绪状态的线程,当时间片轮到该线程执行时,该线程就进入运行状态,此时线程已经拥有处理机的控制权,线程的代码在处理机中执行。时间片用完后,该线程又回到就绪状态。(4)阻塞状态调用Thread.Sleep方法可以使得一个线程进入阻塞状态。进入阻塞状态的线程暂时无法回到线程队列。(5)死亡状态线程执行完毕后将进入死亡状态。16初始就绪运行阻塞死亡Start()时间片轮转到当前线程时间片用完Sleep()睡完Abort()线程执行完毕179.4线程的优先级在线程队列中,线程按照优先级高低顺序排列,优先级高的排在前面。线程的优先级可以被定义为:最高(ThreadPriority.Highest)正常以上(ThreadPriority.AboveNormal)正常(ThreadPriority.Normal)正常以下(ThreadPriority.BelowNormal)最低(ThreadPriority.Lowest)如果不设置优先级,则默认为ThreadPriority.Normal例189.5线程同步同一进程内不同线程可以共享数据,但如果同时对一数据进行读写操作可能会出现混乱。如下图所示。线程1线程2线程10资源变量19例多个线程同时访问共享数据20例使用监视器锁同步线程Monitor类两个静态方法publicstaticvoidEnter(Objectobj)锁住指定对象publicstaticvoidExit(Objectobj)释放指定对象上的监视器锁21例使用lock语句同步线程lock(Objectobj){}执行时对象被锁住执行完成后对象被解锁229.6线程死锁如果甲线程进入FA,然后锁住a1,但是尚未访问b1,这时乙线程进入FB,然后锁住b1,接着乙线程如果试图访问a1,会被阻塞,甲线程如果试图调用b1也会被阻塞,这样甲、乙线程都处于阻塞状态,形成线程死锁。classA{FA(){Monitor.Enter(this);访问b1Monitor.Exit(this);}}classB{FB(){Monitor.Enter(this);访问a1Monitor.Exit(this);}}甲线程代码Aa1=newA();a1.FA();乙线程代码Bb1=newB();b1.FB();