monitor类中Wait,Pulse使用

最近项目中用到多线程,用到是System.Thread中的timer,考虑到每次执行时间可能很长,下次执行到来,上次还没有执行的情况。去msdn中看了下关于多线程中同步的问题,Monitor。看了一段代码,写些自己的感受吧:)

 

代码
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());
        }
    }
}

 

这是msdn上的一段代码,说的是生产者和消费者同步的问题。

tFirst向队列Queue中添加一个数字,tSecond线程则从队列Queue中读取一个数字,实现的是写一次,读一次。

这里先说明下Wait和Pulse这两个方法。

Pulse :通知等待队列中的线程锁定对象状态的更改。(线程调用该方法时并没有释放锁)

wait(object):释放对象上的锁并阻止当前线程,直到它重新获取该锁。

wait(ojbect obj,int n):

释放对象上的锁并阻止当前线程,直到它重新获取该锁。如果指定的超时间隔已过,则线程进入就绪队列。

代码分析:

FirstThread()中,执行第一次循环,Monitor.Wait()该线程就释放掉了锁,这时执行SecondThread()中lock(){}段,执行Monitor.Pulse(m_smplQueue);通知等待队列(这里就是tFirst线程)锁定m_smplQueue的状态更改。 接着while(Monitor.Wait(m_smplQueue,1000)),tSecond线程释放了锁,并阻止了自己,此时tFirst线程开始执行 m_smplQueue.Enqueue(counter); Monitor.Pulse(m_smplQueue);通知等待队列(tSecond)锁定m_smplQueue的状态更改。当循环第二次执行  Monitor.Wait(m_smplQueue);释放锁并阻止自己。while(Monitor.Wait(m_smplQueue,1000)),如果在1秒内线程tSecond重新获取该锁,则返回true,执行while循环。有些人调式的时候可能进不了while循环,是因为你在调试的时候 ,1秒钟早过去了,所以进不了while循环中,调式时可以把1000改大一点,比如10000。

这段代码我现在也有点不明白的地方,但是却说不出个所以然来:(

 

 

 

posted on 2009-12-06 19:53  chaway  阅读(772)  评论(0)    收藏  举报

导航