C#程序设计 第8章多线程
C# 程序设计 第8章 多线程
多线程同步 ★ Lock Monitor Mutex 同步事件 线程池 2
2 多线程同步 ★ Lock Monitor Mutex 同步事件 线程池
本章目标 ■ 了解线程的基本操作及概念 ■掌握如何创建线程 ■掌握如何暂停和恢复线程的执行 ■掌握如何休眠线程 ■掌握如何终止线程的执行 ■掌握线程同步处理 3
3 本章目标 ▪ 了解线程的基本操作及概念 ▪ 掌握如何创建线程 ▪ 掌握如何暂停和恢复线程的执行 ▪ 掌握如何休眠线程 ▪ 掌握如何终止线程的执行 ▪ 掌握线程同步处理
一、线程安全 ■ 线程安全:指在多个线程并发使用某个对象时, 该对象成员总是保持有效状态。常常表现为竞 争资源和死锁现象。 >竞争资源:两个或多个线程同时访问同一数据 或资源时会导致不符合要求或无法预期的结果 。 >死锁:多个线程彼此等待对方释放其所占用的 资源,最终导致线程的阻塞。 4
4 一、线程安全 ▪ 线程安全:指在多个线程并发使用某个对象时, 该对象成员总是保持有效状态。常常表现为竞 争资源和死锁现象。 ➢竞争资源:两个或多个线程同时访问同一数据 或资源时会导致不符合要求或无法预期的结果 。 ➢死锁:多个线程彼此等待对方释放其所占用的 资源,最终导致线程的阻塞
线程同步 ■ 当多个线程可以调用单个对象的属性和方法时, 一个线程可能会中断另一个线程正在执行的任务, 使该对象处于一种无效状态。因此必须针对这些 调用进行同步处理 ■使用Iock语句同步代码块 ■使用监视器同步代码块
5 线程同步 ▪ 当多个线程可以调用单个对象的属性和方法时, 一个线程可能会中断另一个线程正在执行的任务, 使该对象处于一种无效状态。因此必须针对这些 调用进行同步处理 ◼ 使用lock语句同步代码块 ◼ 使用监视器同步代码块
线程同步 ■Lock ■Lock关键字将语句块标记为临界区,方法是获取给定 对象的互斥锁,执行语句,然后释放该锁。 /定义锁或监视对象 各线程所共有的,一般为 Object obj=new objecto. 全局变量或类的成员 Lock(obj》 同步代码 6
6 线程同步 ▪ Lock ◼ Lock关键字将语句块标记为临界区,方法是获取给定 对象的互斥锁,执行语句,然后释放该锁。 //定义锁或监视对象 Object obj=new object(); Lock(obj) { 同步代码 } 各线程所共有的,一般为 全局变量或类的成员
线程同步 Monitor ·Enter((Object)在指定对象上获取排他锁 ·Exit(Object)释放指定对象上的排他锁 try 对象或表达式 { Monitor.Enter(obj)月 dosomething(); finally Monitor.Exit(obj); } 7
7 线程同步 ▪ Monitor ◼ Enter(Object) 在指定对象上获取排他锁 ◼ Exit(Object) 释放指定对象上的排他锁 try { Monitor.Enter( obj ); dosomething(); } finally { Monitor.Exit( obj ); } 对象或表达式
使用Mutex同步代码块 ■ Mutex:创建一个新的互斥对象,该对象在任一 时刻只能被一个线程所拥有。 可以设置等待时间: WaitOne(100,true) Mutex mtx=new Mutex(); 个耳下刈家 mtx.WaitOne();请求互斥对象的所有权:成功为true,否则为false mtx.ReleaseMutex();∥释放对象 ■Pulse或PulseAlli通知等待中的线程 8
8 使用Mutex同步代码块 ▪ Mutex:创建一个新的互斥对象,该对象在任一 时刻只能被一个线程所拥有。 ▪ Pulse或PulseAll通知等待中的线程 Mutex mtx = new Mutex(); //创建一个互斥对象 mtx. WaitOne( ); //请求互斥对象的所有权:成功为true,否则为false mtx.ReleaseMutex ( ); //释放对象 可以设置等待时间: WaitOne(100,true)
案例 C:\Windows\system32\cmd.exe public void M1() 妈妈喊张三回家吃饭 Console.WriteLine("妈妈开始做饭!"); Thread.Sleep(1000); Console.WriteLine("妈妈做好饭了,妈妈喊张三回家吃饭"): public void M2() { Console.WriteLine("张三开始吃饭"); ThreadTest tt new ThreadTest(); Thread t1 new Thread(tt.M1); Thread t2 new Thread(tt.M2); t1.Start(); t2.Start();
9 案例 public void M1() { Console.WriteLine("妈妈开始做饭!"); Thread.Sleep(1000); Console.WriteLine("妈妈做好饭了,妈妈喊张三回家吃饭"); } public void M2() { Console.WriteLine("张三开始吃饭"); } ThreadTest tt = new ThreadTest(); Thread t1 = new Thread (tt.M1 ); Thread t2 = new Thread (tt.M2 ); t1.Start(); t2.Start();
案例 flag=false; C:\Windows\system32\cmd.exe 一回x public void M1() 妈妈开始做饭』 妈妈喊张三回家吃饭 if(flag==false) { Console.WriteLine("妈妈开始做饭!"); Thread.Sleep(1000); Console.WriteLine("妈妈做好饭了,妈妈喊张三回家吃饭"); flag=true; ThreadTest tt new ThreadTest(); } Thread t1 new Thread(tt.M1); public void M2() Thread t2 new Thread(tt.M2); if(flag==true) t1.Start(); t2.Start(); Console.WriteLine("张三开始吃饭"); 10
10 案例 flag=false; public void M1() { if(flag==false) { Console.WriteLine("妈妈开始做饭!"); Thread.Sleep(1000); Console.WriteLine("妈妈做好饭了,妈妈喊张三回家吃饭"); flag=true; } } public void M2() { if(flag==true) { Console.WriteLine("张三开始吃饭"); } } ThreadTest tt = new ThreadTest(); Thread t1 = new Thread (tt.M1 ); Thread t2 = new Thread (tt.M2 ); t1.Start(); t2.Start();