验证Monitor.PulseAll功效

PulseAll MSDN:通知所有的等待线程对象状态的更改。

所以可以理解成所有Wait锁对象的线程都将变成就绪状态。而Pulse顾名思义,只能将排在最前面的Wait就绪。

非常简单吧,下的示例可以说明PulseAll的功能,线程1启动之后会进入Wait状态,紧接着线程3获得锁对象但也马上Wait,然后线程3获得锁对象就PulseAll了。

PulseAll的结果就是前面两个Wait得到释放,在执行完2之后,1和3都将得到执行。如果此处用的是Pulse,则3将一直处于Wait状态。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static object _lockObject = new object();
        static Thread tr1;
        static Thread tr2;
        static Thread tr3;
        static void Main(string[] args)
        {
            tr1 = new Thread(ThreadProc1);
            tr2 = new Thread(ThreadProc2);
            tr3 = new Thread(ThreadProc3);
            tr1.Start();
            tr3.Start();
            Thread.Sleep(1000);
            tr2.Start();
            tr1.Join();
            tr2.Join();
            tr3.Join();
            Console.ReadKey();
        }

        static void ThreadProc1()
        {
            lock(_lockObject)
            {
                Monitor.Wait(_lockObject);
                //Monitor.Wait(_lockObject);
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("1");
                }   
            }
        }

        static void ThreadProc3()
        {

            lock (_lockObject)
            {
                Monitor.Wait(_lockObject);
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("3");
                }
            }
        }

        static void ThreadProc2()
        {
            lock (_lockObject)
            {
                Console.WriteLine("2");
                Monitor.PulseAll(_lockObject);
            }

        }
    }
}

那麽2之后1,3究竟是谁先执行呢,这涉及系统的线程调度优先级问题。这里仅做一个简单的实验,将th1的优先级设为最高,tr3的设为最低,我们看到果真1先于3执行;同理反之亦然。

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static object _lockObject = new object();
        static Thread tr1;
        static Thread tr2;
        static Thread tr3;
        static void Main(string[] args)
        {
            tr1 = new Thread(ThreadProc1);
            tr2 = new Thread(ThreadProc2);
            tr3 = new Thread(ThreadProc3);
            tr1.Priority = ThreadPriority.Highest;
            tr3.Priority = ThreadPriority.Lowest;
            tr1.Start();
            tr3.Start();
            Thread.Sleep(1000);
            tr2.Start();
            tr1.Join();
            tr2.Join();
            tr3.Join();
            Console.ReadKey();
        }

        static void ThreadProc1()
        {
            lock(_lockObject)
            {
                Monitor.Wait(_lockObject);
                //Monitor.Wait(_lockObject);
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("1");
                }   
            }
        }

        static void ThreadProc3()
        {

            lock (_lockObject)
            {
                Monitor.Wait(_lockObject);
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine("3");
                }
            }
        }

        static void ThreadProc2()
        {
            lock (_lockObject)
            {
                Console.WriteLine("2");
                Monitor.PulseAll(_lockObject);
            }

        }
    }
}

posted @ 2012-03-26 23:54  Dance With Automation  Views(1013)  Comments(0Edit  收藏  举报