- 1、本文档共48页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C_多线程技术
lock 与Monitor 区别 lock 锁定一段代码,Monitor 锁定一个对象。 当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock 关键字了, 这里需要用到System.Threading 中的一个类Monitor,我们可以称之为监视器,Monitor 提供了使线程共享资源的方案。 Monitor 类可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了 在可能引起混乱的情况下一个时刻只有一个线程可以访问这个对象。 Monitor 必须和一个具体的对象相关联,但是由于它是一个静态的类,所以不能使用它来定义对象,而且它的所有方法都是静态的,不能使用对象来引用。下面代码说明了使用Monitor 锁定一个对象的情形: ...... Queue oQueue=new Queue(); ...... Monitor.Enter(oQueue); ......//现在oQueue 对象只能被当前线程操纵了 Monitor.Exit(oQueue);//释放锁 如上所示,当一个线程调用 Monitor.Enter()方法锁定一个对象时,这个对象就归它所有了,其它线程想要访问这个对象,只有等待它使用Monitor.Exit()方法释放 锁。(在一个线程运行的代码里面调用Monitor.Enter(对象),那么其它线程就不能使用该对象了) 为了保证线程最终都能释放锁,你可以Monitor.Exit()方法写在try-catch-finally 结构中的finally代码块里。 对于任何一个被 Monitor 锁定的对象,内存中都保存着与它相关的一些信息: 其一是现在持有锁的线程的引用; 其二是一个预备队列,队列中保存了已经准备好获取锁的线程; 其三是一个等待队列,队列中保存着当前正在等待这个对象状态改变的队列的引用。 获取的过程:当拥有对象锁的线程准备释放锁时,它使用 Monitor.Pulse()方法通知等待队列中的第一个线程,于是该线程被转移到预备队列中,当对象锁被释放时,在预备队列中的线程可以立即获得对象锁。 3、同步时要注意的问题 线程同步非常重要,但只在需要时使用也是非常重要的。因为这会降低性能。原因有两个: 首先,在对象上放置和解开锁会带来某些系统开销,但这些系统开销都非常小。第二个原因更为重要,线程同步使用得越多,等待释放对象的线程就越多。如果一个线程在对象上放置了一个锁,需要访问该对象的其他线程就只能暂停执行,直到该锁被解开,才能继续执行。因此,在lock块内部编写的代码越少越好,以免出现线程同步错误。lock语句在某种意义上就是临时禁用应用程序的多线程功能,也就临时删除了多线程的各种优势。 6.6多线程的自动管理 在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响 应这一般使用 ThreadPool(线程池)来解决; 另一种情况:线程平时都处于休眠状态,只是周期性地被唤醒这一般使用 Timer(定时器)来解决; 1、多线程的自动管理(定时器Timer) Timer 类:设置一个定时器,定时执行用户指定的函数。 定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数。 初始化一个 Timer 对象: Timer timer = new Timer(timerDelegate, s,1000, 1000); // 第一个参数:指定了TimerCallback 委托,表示要执行的方法; // 第二个参数:一个包含回调方法要使用的信息的对象,或者为空引用; // 第三个参数:延迟时间——计时开始的时刻距现在的时间,单位是毫秒,指定为“0”表示立即启动计时器; // 第四个参数:定时器的时间间隔——计时开始以后,每隔这么长的一段时间,TimerCallback 所代 表的方法将被调用一次,单位也是毫秒。指定 Timeout.Infinite 可以禁用定期终止。 Timer.Change()方法:修改定时器的设置。(这是一个参数类型重载的方法). timer.Change(1000,2000); 2、多线程的自动管理(线程池) ThreadPool类提供一个由系统维护的线程池(可以看作一个线程的容器),该容器需要 Windows 2000以上系统支持,因为其中某些方法调用了只有高版本的Windows 才有的API 函数。 将线程安放在线程池里,需使用 ThreadPool.QueueUserWorkItem()方法,该方法的原型如下: //将一个线程放进线程池,该线程的Start()方法将调用WaitCallback 代理对象代表的函数 public static bool Qu
文档评论(0)