首页 新闻 会员 周边 捐助

.Net 请教几个多线程的菜鸟问题。。。

0
悬赏园豆:10 [已解决问题] 解决于 2012-01-04 13:02

请问:

1: Monitor.Enter(this)和Monitor.Exit(this);他们的功能是什么?

2: Monitor.Wait(this)和Monitor.Pulse(this);他们的功能是什么?

3:我在MSDN找了,看不懂,请问上边2个组合什么时候用哪种?他们之间有什么区别呢?请高手指点,谢谢!

hexllo的主页 hexllo | 菜鸟二级 | 园豆:318
提问于:2011-11-21 15:46
< >
分享
最佳答案
0

Enter是获取锁对象,Exit是释放锁对象

Wait是释放锁对象并等待通知,Pulse是通知等待中的线程

有可能当前线程A在Enter和Exit之间,需要等待另一个线程B执行一些操作,而线程B正在等待同一个锁对象,这时就是Wait和Pulse的应用场景了,线程A调用Wait暂时释放锁对象,由线程B获取锁对象,线程B完成任务后调用Pulse通知正在等待的线程A就绪,当线程B释放了锁对象后,线程A继续工作。

 

参考msdn

http://msdn.microsoft.com/zh-cn/library/system.threading.monitor.pulse.aspx

收获园豆:10
klice | 初学一级 |园豆:173 | 2011-12-31 17:10
其他回答(2)
0

Monitor.Enter(this)是锁定,Monitor.Exit(this);是解除锁定

Monitor.Wait(this)释放对象上的锁以便允许其他线程锁定和访问该对象

Monitor.Pulse(this);通知等待队列中的线程锁定对象状态的更改。只有锁的当前所有者可以使用   Pulse   向等待对象发出信号。

artwl | 园豆:16736 (专家六级) | 2011-11-21 20:33

我感觉他们的功能都差不多啊。。锁定和解锁。。

请问这两种组合。。在实际应用中是分开用的吗?哪种用得多一些呢?谢谢 !

 

支持(0) 反对(0) hexllo | 园豆:318 (菜鸟二级) | 2011-11-29 09:57
0

想是你困惑于使用上。

先了解一下Moniter背后的故事:

     每个对象实例头部都有一个指针,这个指针指向的结构,包含了对象的锁定信息,当第一次使用Moniter.Enter(obj)时,这个obj对象的锁定结构就会被初时化,第二次调用Moniter.Enter时,会检验这个object的锁定结构,如果锁没有被释放,则调用会阻塞。

  lock或者Moniter是.net用一个特殊结构实现的,不涉及模式切换,也就是说工作在用户方式下,同步速度较快,但是不能跨进程同步。

有了以上了解,再来理解就顺多了。

    Moniter 使用必须 Moniter.Enter(obj)开始(可能CLR会背地里调用,如lock),这里会有一些初始化工作量,如果进程中反复对同一个obj多次Moniter.Enter(obj)是不好的设计表现。

     也就是说,知道确认不在需要是,才调用Moniter.Exit(obj).

     Moniter.Wait(obj)调用,线程释放资源的独占锁,并且阻塞在wait方法直到另外的线程获取资源的独占锁后,更新资源信息并调用Moniter.Pulse(obj)方法后返回。

     Moniter.Pulse(obj) 调用,通知等待队列中的第一个线程,于是该线程被转移到预备队列中,并释放对象锁。这是,在预备队列中的线程可以立即获得对象锁。

     补充,以上内容借用了多个大牛的原话,由于没有记录原文链接地址,还请见谅。

胡屯 | 园豆:714 (小虾三级) | 2011-12-09 16:42

可能是我水平太菜吧,你回答的还是看得不大明白,你能告诉我这两个组合分别用于什么情况下吗?

比如我要等A线程处理完对象X后,再让B线程去调用对调X...这样吧,你帮我个忙,给我段C#代码,在A线程中建立一个文件D:\x.txt后强制占用它10秒,B线程必须等A线程解除占用后,往x.txt写入"Finished",谢谢了!

支持(0) 反对(0) hexllo | 园豆:318 (菜鸟二级) | 2011-12-22 16:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册