+ -
当前位置:首页 → 问答吧 → 请问,这个关于多线程的代码不懂

请问,这个关于多线程的代码不懂

时间:2011-12-08

来源:互联网

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 方法必须从同步的代码块内调用。 此话怎讲?我上面的代码似乎就没有这样,没报错呢?

作者: q2fdaw2   发布时间: 2011-12-08

threadPing.Start();
  threadPong.Start();

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

作者: sp1234   发布时间: 2011-12-09

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

作者: sp1234   发布时间: 2011-12-09

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

作者: Sandy945   发布时间: 2011-12-09

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

lock (ball)
  {
  Monitor.Pulse(ball); 
  }
lock 就是同步块

作者: Sandy945   发布时间: 2011-12-09

lock (ball)
  {
  for (int i = 0; i < 5; i++)
  {
  System.Console.WriteLine("李四 ");
  Monitor.Pulse(ball); 
  }
  }
--------------
这个其实写法是有些问题,虽然它可以work 

应该改成

C# code

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可以继续执行

作者: Sandy945   发布时间: 2011-12-09

相关阅读 更多