




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本章常见错误
本讲大纲:1、使用值类型进行线程同步的错误支持网站:2、多个线程调用同一静态方法的运行结果问题使用值类型进行线程同步的错误(1)无论在什么环境和机制下编写多线程程序,都需要考虑线程同步的问题,因为很难找到同属于一个应用程序却又完全不相干的多线程。下面将演示使用值类型进行线程同步时容易出现的错误,实现过程如下:创建一个控制台应用程序,首先在应用程序下创建一个类文件SynchronValue.cs,该文件包含一个名称叫SynchronValue的类,其代码如下:publicclassSynchronValue{privateintsyn=0;//定义值类型的同步变量
privateinti=0;publicvoidDoWork(objectstate){try{Monitor.Enter(syn);//使用值类型对象同步
Console.WriteLine("i的值为:"+i.ToString());i++;Thread.Sleep(100);//模拟其它的工作
Console.WriteLine("i自增1后的值为:"+i.ToString());Monitor.Exit(syn);//移除同步
}catch(Exceptionex){throwex;}}}使用值类型进行线程同步的错误(2)在控制台应用程序的入口方法Main中编写如下代码:staticvoidMain(string[]args){SynchronValuesv=newSynchronValue();for(inti=0;i<5;i++)//5个线程同步测试
{Threadthrd=newThread(sv.DoWork);thrd.Start();//开启线程
}Thread.Sleep(1000);//休眠1秒钟,保证所有的内容都已输出到控制台}编译后运行程序,在运行时却出现如图所示的异常提示窗口,异常信息提示:“从不同步的代码块中调用了对象同步方法”。
下面对上面的异常提示进行分析:.NET的线程同步机制是基于同步块实现的,在.NET的框架中,每个堆内的对象都会拥有一个同步索引字段,用来指向同步块的位置。值类型对象是分配在堆栈上的,也就是说值类型对象没有同步索引字段,所以直接使用值类型对象无法实现线程同步。具体应用到程序中,对值类型的变量使用lock关键字或者Monitor类的Enter方法和Exit方法会产生不一样的结果。对于lock关键字来说,使用值类型会直接导致一个编译错误,错误信息如图所示。使用值类型进行线程同步的错误(3)但是如果使用Monitor类,编译器则无法检测出这一类的错误,和使用引用类型的情况一样,每次调用Monitor.Enter方法时,都会对值类型进行装箱,每一次装箱都会导致一个新的堆内对象的产生,所有的线程都在访问不同对象的同步块,导致线程同步完全失败。更为严重的是,当某个线程试图对值类型对象调用Monitor.Exit方法时,装箱同样会发生,这时就意味着程序尝试对一个没有分配同步块的对象进行同步退出,所以才会导致如上图所示的运行时异常。根据上面的分析可知,不可以使用值类型进行线程同步,所以解决方法是将SynchronValue类中的syn字段修改为引用类型,修改后的代码如下:publicclassSynchronValue{privateobjectsyn=newobject();//定义引用类型的同步变量
privateinti=0;publicvoidDoWork(objectstate){…//方法中的其它代码
}}多个线程调用同一静态方法的运行结果问题(1)静态成员属于类,而不属于实例,通常使用类直接调用,而无法使用类的实例调用。由于静态成员的这些特性,使其给程序设计人员带来一种神秘感,同时也增加了一些人对静态成员的的诸多猜测。比如,静态方法效率比实例方法高、静态方法比实例方法占内存、多个线程同时调用静态方法,其运行结果可能不准确等等。下面的代码使用3个线程同时调用同一个静态方法,代码如下:staticvoidMain(string[]args){for(inti=0;i<3;i++)//同时执行3个线程
{Threadt=newThread(MyFunction); //创建线程
t.Name="t"+i.ToString();//设置线程的名称
t.Start();//启动线程
}Console.Read();}staticvoidMyFunction()//定义一个静态方法{Console.WriteLine(Thread.CurrentThread.Name+"开始线程...");Thread.Sleep(10000);//模拟做一些耗时的工作
Console.WriteLine(Thread.CurrentThread.Name+"结束线程...");}
多个线程调用同一静态方法的运行结果问题(2)在上面代码的Main方法中,同时创建并启动3个线程,这3线程都绑定了静态方法MyFunction。编译并运行上面的代码,其运行结果如图所示。从运行结果可以看
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 经济模型构建与数据分析手册
- 财务管理基础要点解析与实践指导
- 农产品电商知识培训课件
- 建筑行业设计风格表格
- 合同之手房代理合同
- 事务流程改进指南
- 2025年福州货运从业资格证模拟考试软件
- 任务6.3.3 厂房构件安装测量
- 三农村资源综合利用方案
- 2025年保定幼儿师范高等专科学校单招综合素质考试题库新版
- 抖音博主在线写电脑配置同款表格
- 品质基础及品质意识培训资料
- 《金融科技学》教案全套及习题答案(李建军版)
- 输液泵操作评分标准
- 苏州大学课件模板(经典)
- 水电清包工合同水电清包工合同
- 酒店财务管理PPT完整全套教学课件
- 小学综合实践活动-《制作环保提示牌》教学课件设计
- 《公共伦理学》课程教学大纲
- “四议两公开”模板范文(精选6篇)
- 四川省建筑保温节能工程材料、构件及设备检测服务收费项目和标准-川发改价格【2012】369号
评论
0/150
提交评论