通过最简单的例程来理解线程同步问题

我们用代码来认识一下下面几类的作用
AutoResetEvent / ManualResetEvent    Monitor
-----------------------
首先来看看 AutoResetEvent 和 ManualResetEvent

class Program
    
{
        
static AutoResetEvent are = new AutoResetEvent(false);

        
static void threadProc()
        
{
            Thread currentThread 
= Thread.CurrentThread;
            
for (int i = 0; i < 100; i++)
            
{
               are.WaitOne();
               Console.WriteLine(
"Name:{0} : {1}", currentThread.Name, i);
            }

        }


        
static void Main(string[] args)
        
{
            Thread t 
= new Thread(new ThreadStart(threadProc));
            t.Name 
= "TestThread1";
            t.Start();

            
for (int i = 0; i < 500; i++)
            
{
                
if ((i % 5== 0)
                
{
                    are.Set();
                    Thread.Sleep(
10);
                }

                Console.WriteLine(
"pulse:{0}", i);

                
            }


            
while (t.IsAlive)
            
{
                t.Abort();
            }


            Console.ReadLine();
        }

    }

 

正和我们想像的一样,在主线程,每打印5个数,子线程被激活
程序一开始,子线程由于 AutoResetEvent 的 WaitOne方法阻塞 , 这个阻塞只有当收到 AutoResetEvent 的Set方法通知时,才进入运行状态, Set方法发出的通知一方面让处于Wait的子线程进入运行状态,另外一方面,他会阻塞当前线程。

 

下面我们来看看 Monitor 如何工作

class Program
    
{
        
static object tLock = new object();

        
static void threadProc()
        
{
            Thread currentThread 
= Thread.CurrentThread;
            
for (int i = 0; i < 100; i++)
            
{
                
lock (tLock)
                
{
                    Monitor.Pulse(tLock);
                    Monitor.Wait(tLock);

                    Console.WriteLine(
"Name:{0} : {1}", currentThread.Name, i);
                }

            }

        }


        
static void Main(string[] args)
        
{
            Thread t 
= new Thread(new ThreadStart(threadProc));
            t.Name 
= "TestThread1";
            t.Start();

            
lock (tLock)
            
{
                
for (int i = 0; i < 500; i++)
                
{
                    
if ((i % 5== 0)
                    
{
                        Monitor.Pulse(tLock);
                        Monitor.Wait(tLock);
                    }

                    Console.WriteLine(
"pulse:{0}", i); 
                }

            }


            
while (t.IsAlive)
            
{
                t.Abort();
            }


            Console.ReadLine();
        }


    }

 

上面两个程序达到一个目的

在一些时常的线程程序开发中,很多人习惯 Lock(this) ,其实种做法也不是最佳的,在有些情况下会产生的些问题,这里就不讨论了,微软的MSDN建议我们最好Lock一个静态的私有引用类型,建议不用string

希望上面两个小例程能给你解决线程同步问题上带来帮助
上文及例程,代表人个学习的观点,非官方权威解释,不尽之处,请斧正

 

posted @ 2008-07-22 11:03  悟水  阅读(250)  评论(0)    收藏  举报