public class Program
    {
        static object ball = new object();
        public static void Main()
        {
            Thread threadPing = new Thread(ThreadPingProc);
            Thread threadPong = new Thread(ThreadPongProc);
            threadPing.Start();
            threadPong.Start();
            Console.ReadKey();
        }
        static void ThreadPingProc()
        {
            lock (ball)
            {
                for (int i = 0; i < 5; i++)
                {
                    System.Console.WriteLine("张三 ");                    
                    Monitor.Wait(ball);
                }
            }
        }
        static void ThreadPongProc()
        {
            lock (ball)
            {
                for (int i = 0; i < 5; i++)
                {
                    System.Console.WriteLine("李四 ");
                    Monitor.Pulse(ball);                   
                }
            }
        }
    }
两个问题:
1:首先执行 threadPing.Start();所以,无论如何,第一句都该是"张三"吧,可为什么多执行几次,第一句有时候是"李四"2:MSDN说的,
Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用。 此话怎讲?我上面的代码似乎就没有这样,没报错呢?

解决方案 »

  1.   

      threadPing.Start();
      threadPong.Start();这也不过是向系统注册了线程启动要求,这个Start操作立刻结束了,而此时并没有执行你要执行的方法。
      

  2.   

    至于第二个问题,其实你的程序都是lock而互斥的,在里边写那些代码已经毫无意义了,因为它们根本不可能并发执行。
      

  3.   

    1:首先执行 threadPing.Start();所以,无论如何,第一句都该是"张三"吧,可为什么多执行几次,第一句有时候是"李四"
    ------------------------
    这个不是绝对的,要看CPU的工作情况。 如果碰巧分配时间片的时候顿了一下,那么就不会和你代码的顺序一致了。就是这个不一定是按照你代码的顺序执行的。虽然大多数情况是(CPU低负载)
      

  4.   

    2:MSDN说的,
    Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用。 此话怎讲?我上面的代码似乎就没有这样,没报错呢?
    ---------------------
    lock (ball)
      {
           Monitor.Wait(ball);  
      }lock (ball)
      {
        Monitor.Pulse(ball); 
      }
    lock 就是同步块 
      

  5.   

    lock (ball)
      {
      for (int i = 0; i < 5; i++)
      {
      System.Console.WriteLine("李四 ");
      Monitor.Pulse(ball); 
      }
      }
    --------------
    这个其实写法是有些问题,虽然它可以work 应该改成
    lock (ball)
    {
      for (int i = 0; i < 5; i++)
      {
          System.Console.WriteLine("李四 ");
      }
      Monitor.Pulse(ball); 
    }因为for循环在ThreadPongProc的lock (ball){} 中, 就算调用了Monitor.Pulse(ball)张三也不会输出,因为 ball 在循环结束前一直是锁定状态所以在循环后调用一次 Monitor.Pulse(ball) 就可以了,告知ThreadPingProc可以继续执行
      

  6.   

    你的意思是Pulse和Wait要同时出现在同一个Lock语句中吗?
    这是为什么啊?
      

  7.   

    为什么Pulse和Wait要同时出现在同一个Lock语句中?
    这是为什么啊?
      

  8.   

    static void ThreadPingProc()
      {
      lock (ball)
      {
      for (int i = 0; i < 5; i++)
      {
      System.Console.WriteLine("张三 ");   
      Monitor.Wait(ball);  }
      }
      }
    ---------------------------------
      static void ThreadPongProc()
      {
      lock (ball)  {
      for (int i = 0; i < 5; i++)
      {
      System.Console.WriteLine("李四 ");
      Monitor.Pulse(ball);   }
      }
      }
      

  9.   

    Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用。
    -------------------------------------------------
    同步的代码块指的就是lock (ball)
    {}你看看你的  Pulse 和 Wait  是不是都在 lock 内调用的
     
      

  10.   

    lz是不是从这里摘抄的?http://www.cnblogs.com/free722/archive/2011/03/25/1995136.html
    这已经说的很明白了啊
      

  11.   

    我就是不明白,为什么Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用?
      

  12.   

    因为在lock 内,你才对被lock住的对象有所有权   (hold住?)你才有权利进行 Pulse、Wait 等方法你不在同步代码块内,是没权利 Pulse、Wait 的
      

  13.   

    我的例子中,Pulse和Wait都是在Lock内部使用的啊,一个Lock一个
      

  14.   

    我的例子中,Pulse和Wait都是在Lock内部使用的啊,一个Lock一个
      

  15.   

    我的例子中,Pulse和Wait都是在Lock内部使用的啊,只不过是一个Lock写了一个
    这能说明Pulse、PulseAll 和 Wait 方法是从同步的代码块内调用的吗?
    还是说,一个Lock语句块内部,必须即写Pulse,又要写Wait
      

  16.   

    和你写几个lock 没关系,是Pulse、PulseAll 和 Wait 必须写在lock 内lock 内 Pulse、PulseAll 和 Wait  你可以写多个 也可以不写不是一定要固定的
      

  17.   

    Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用,就是必须写在Lock块内部吗?写在外部为什么不行?
    此话的意思,是不是不允许Pulse和Wait同时进行?
      

  18.   

    哦,mygod
    那为什么Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用,必须写在Lock块内部?
      

  19.   

    绕圈圈啊~  又绕回来了lock 你知道是什么意思么
      

  20.   

    Lock知道啊,互斥锁啊,每次只允许一条线程执行
      

  21.   

    就是说进入lock 块内  才对被lock住的对象 有所有权其他都要等待。只有有所有权的 才有权利 对被lock 的对象进行 Pulse、PulseAll 和 Wait 其他是没有权利的。 因为lock住的对象的所有权它们没有
      

  22.   

    那“Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用” 
    其意思完全等于:
    Pulse、PulseAll 和 Wait 方法必须写在Lock语句块内
    是这样的吗?
      

  23.   

     class Program
        {
            private static object ball=new object();
            static void Main(string[] args)
            {
                System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(Show));
                System.Threading.Thread s = new System.Threading.Thread(new System.Threading.ThreadStart(Display));
                s.Priority = System.Threading.ThreadPriority.Highest;
                t.Priority = System.Threading.ThreadPriority.Lowest;
                t.Start();
                s.Start();
                Console.Read();
            }        static void Show()
            {
                lock (ball)
                {                for (int i = 0; i < 5; i++)
                    {                    System.Console.WriteLine("张三 ");
                        System.Threading.Monitor.Wait(ball);
                    }
                }
      
            }
            static void Display()
            {
                lock (ball)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        System.Console.WriteLine("李四 ");
                        System.Threading.Monitor.Pulse(ball);
                    }
                }        }
        }首先线程的调用有操作系统来管理的,我设置了调度级别,所以T线程先start,但是S线程先跑的。
    线程的调用优先级,你可以试试
      

  24.   

    其实,是这样的吧
    Wait、Pulse的阻塞、唤醒,只能对同一对象锁起作用,此Pulse不能唤醒彼Wait
    ok ?这样阐释,不知对否?
      

  25.   

    Wait 是放弃控制权,放弃对谁的控制权呢 就是Wait 方法的参数实例的控制权.当一个线程调用 Wait 方法时,它将会失去对相应实例的控制权,进入WaitSleepJoin状态直至有人通知它。如何通知呢,就是 Pulse 方法, Pulse 方法是通知 ,通知谁呢  通知处于等待 Pulse 方法参数实例的队列, 因为会是多个线程在等待。但是只会有一个线程被告知可以work 。 类似排号就医 
      

  26.   

    这位老兄和你是同路人,
    你可以看看他的帖子,
    http://topic.csdn.net/u/20111206/15/744c70de-49dc-4694-a09e-180438d7f8f0.html