如果某个线程在当前没有的锁定对象上调用Monitor.Wait(lockObj)
,则会抛出SyncronizationLockException
。
我不明白这一点?如果线程拥有锁,因此可以成功调用Monitor.Wait()
,那么它只是会立即释放锁。为什么线程不能等待它当前不拥有的锁?
更新
我决定在我的问题上添加一些解释。
据我所知,Wait只是将当前线程放在监视器等待队列中并释放锁定。稍后脉冲或脉冲都将等待队列上的一个或所有线程移动到就绪队列。每当监视器被释放时,就绪队列上的下一个(如果有的话)线程都会被锁定。
那为什么不等待只是将线程添加到等待队列?为什么需要获取锁来执行此操作?是否存在物理原因,或者仅仅是微软设计的类强制您以正确的方式使用它?
现在我考虑一下,我想在监视器的等待队列中放置一些东西,或者将某些内容移动到就绪队列实际上是在操纵监视器。您需要拥有监视器才能执行此操作。这是正确的思考方式吗?
我的大脑多线程很难!
答案 0 :(得分:1)
Monitor.Wait
的目的是让其他线程有机会抓住你的锁。
如果你没有首先拥有锁,那就没有意义了;其他线程已经可以抓住锁
(除非其他一些线程已经拥有锁,在这种情况下调用Wait
会弄乱该线程)
答案 1 :(得分:1)
Monitor.Wait
用于释放锁定,然后以原子方式重新获取 。 BCL中没有其他同步机制声名鹊起。显然Wait
如果尚不存在,则无法重新获取锁。这就是抛出异常的原因。
Wait
重新获取现有锁的事实是一种非常强大的机制。行为中的这种基本唯一性允许它用于构建BCL中的所有其他同步机制。
答案 2 :(得分:0)
在没有锁定的情况下调用Monitor.Wait
在大多数情况下会引入一个非确定性错误。如果您在获取锁定之后立即调用Monitor.Wait
并且在获取锁定和调用Monitor.Wait
之间未设置任何共享变量时也是如此。
特别是 - 如果您没有锁,那么在输入Monitor.Pulse
之前,您永远不能确定附带的Monitor.Wait
是否已被执行。考虑操作系统在Monitor.Wait
调用之前挂起线程A并在执行某些计算后恢复正在执行Monitor.Pulse
的线程B的情况。所有共享变量都说服线程B A正在等待,但这还不是真的。并且线程A此时无法停止执行Monitor.Wait
。
另外 - 您可能对Semaphores http://en.wikipedia.org/wiki/Semaphore_(programming)的想法感兴趣。您可以等待并发出信号,而无需获取它们。这是因为他们在其中持有一个州。所以,如果你先发信号,那么等待就不会锁定。