等待通知经典模式

Monitor.Pulse 方法

Monitor.Wait方法

while(value!=desire){

Thread.sleep(1000)

}

doSomethine()

两个问题:1.及时性,2开销

通知模式 wait()和notify()

等待方

Monitor.Wait(object);

doSomethine();

通知方

条件发生改变
Monitor.Pulse(object);
obejct这个数据为消息来 协同和线程间通信。


通知对

ManualResetEvent和AutoResetEvent


==================





只有锁的当前所有者可以使用 Pulse 向等待对象发出信号。

当前拥有指定对象上的锁的线程调用此方法以便向队列中的下一个线程发出锁的信号。接收到脉冲后,等待线程就被移动到就绪队列中。在调用 Pulse 的线程释放锁后,就绪队列中的下一个线程(不一定是接收到脉冲的线程)将获得该锁。

Note重要事项:

Monitor 类不对指示 Pulse 方法已被调用的状态进行维护。因此,如果您在没有等待线程时调用 Pulse,则下一个调用 Wait 的线程将阻止,似乎 Pulse 从未被调用过。如果两个线程正在使用 Pulse 和 Wait 交互,则可能导致死锁。将其与 AutoResetEvent 类的行为相比较:如果您通过调用 AutoResetEvent 的 Set 方法向其发送信号,在没有等待线程时,AutoResetEvent 将一直保持终止状态,直到线程调用 WaitOneWaitAny或 WaitAllAutoResetEvent 释放该线程并返回到未终止状态。

请注意,同步的对象包含若干引用,其中包括对当前拥有锁的线程的引用、对就绪队列(包含准备获取锁的线程)的引用和对等待队列(包含等待对象状态更改通知的线程)的引用。

Pulse、 PulseAll 和 Wait 方法必须从同步的代码块内调用。

若要向多个线程发送信号,请使用 PulseAll 方法。

下面的代码示例说明如何使用 Pulse 方法。

using System;
using System.Threading;
using System.Collections;

namespace MonitorCS1
{
	class MonitorSample
	{
		const int MAX_LOOP_TIME = 1000;
		Queue	m_smplQueue;

		public MonitorSample()
		{
			m_smplQueue = new Queue(); 
		}
		public void FirstThread()
		{
			int counter = 0;
			lock(m_smplQueue)
			{
				while(counter < MAX_LOOP_TIME)
				{
					//Wait, if the queue is busy.
					Monitor.Wait(m_smplQueue);
					//Push one element.
					m_smplQueue.Enqueue(counter);
					//Release the waiting thread.
					Monitor.Pulse(m_smplQueue);	

					counter++;
				}
			}
		}
		public void SecondThread()
		{
			lock(m_smplQueue)
			{
				//Release the waiting thread.
				Monitor.Pulse(m_smplQueue);
				//Wait in the loop, while the queue is busy.
				//Exit on the time-out when the first thread stops. 
				while(Monitor.Wait(m_smplQueue,1000))
				{
					//Pop the first element.
					int counter = (int)m_smplQueue.Dequeue();
					//Print the first element.
					Console.WriteLine(counter.ToString());
					//Release the waiting thread.
					Monitor.Pulse(m_smplQueue);
				}
			}
		}
		//Return the number of queue elements.
		public int GetQueueCount()
		{
			return m_smplQueue.Count;
		}

		static void Main(string[] args)
		{
			//Create the MonitorSample object.
			MonitorSample test = new MonitorSample();			
			//Create the first thread.
			Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
			//Create the second thread.
			Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
			//Start threads.
			tFirst.Start();
			tSecond.Start();
			//wait to the end of the two threads
			tFirst.Join();
			tSecond.Join();			
			//Print the number of queue elements.
			Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
		}
	}
}

本文档已存档,并且将不进行维护。

ManualResetEvent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值