请问,这个关于多线程的代码不懂
时间: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 方法必须从同步的代码块内调用。 此话怎讲?我上面的代码似乎就没有这样,没报错呢?
{
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操作立刻结束了,而此时并没有执行你要执行的方法。
threadPong.Start();
这也不过是向系统注册了线程启动要求,这个Start操作立刻结束了,而此时并没有执行你要执行的方法。
作者: sp1234 发布时间: 2011-12-09
至于第二个问题,其实你的程序都是lock而互斥的,在里边写那些代码已经毫无意义了,因为它们根本不可能并发执行。
作者: sp1234 发布时间: 2011-12-09
1:首先执行 threadPing.Start();所以,无论如何,第一句都该是"张三"吧,可为什么多执行几次,第一句有时候是"李四"
------------------------
这个不是绝对的,要看CPU的工作情况。 如果碰巧分配时间片的时候顿了一下,那么就不会和你代码的顺序一致了。就是这个不一定是按照你代码的顺序执行的。虽然大多数情况是(CPU低负载)
------------------------
这个不是绝对的,要看CPU的工作情况。 如果碰巧分配时间片的时候顿了一下,那么就不会和你代码的顺序一致了。就是这个不一定是按照你代码的顺序执行的。虽然大多数情况是(CPU低负载)
作者: Sandy945 发布时间: 2011-12-09
2:MSDN说的,
Pulse、PulseAll 和 Wait 方法必须从同步的代码块内调用。 此话怎讲?我上面的代码似乎就没有这样,没报错呢?
---------------------
lock (ball)
{
Monitor.Wait(ball);
}
lock (ball)
{
Monitor.Pulse(ball);
}
lock 就是同步块
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
因为for循环在ThreadPongProc的lock (ball){} 中, 就算调用了Monitor.Pulse(ball)
张三也不会输出,因为 ball 在循环结束前一直是锁定状态
所以在循环后调用一次 Monitor.Pulse(ball) 就可以了,告知ThreadPingProc可以继续执行
{
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
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28