学习 C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(上) 并且给出源码的改进版
Posted on 2008-07-31 20:57 秦奋 阅读(834) 评论(0) 收藏 举报声明、本人也是初次接触线程,写此文章只为分享学习经验,并无它意。
1、为什么说是改进版?
原文是实现功呢是两个线程同时操作一个数据
一个线程操作完毕,释放锁,另一个线程操作,释放锁,循环直到程序结束
使用的等待方法是
为了达到举一反三的效果,特把原来程序改为
一个线程等待另外两个线程全部完毕后执行操作
并且使用 Wait(Object) 方法
并且写有相关提示,使阅读代码者能够了解线程的执行方法
2、先给出源代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ThreadMonitorDemo
{
class MonitorClass
{
private int n = 1;
private int m = 1;
private int max = 10;
private object createrN = new object();
private object craeterM = new object();
public void ProduceN()
{
lock (createrN)
{
for (; n < max; n++)
{
Console.WriteLine("释放 n=" + n.ToString());
//Monitor.Pulse(createrN);
bool isReleaseN = Monitor.Wait(createrN);
Console.WriteLine("Consume 调用方重新获取了createrN的锁 " + isReleaseN.ToString());
}
}
Console.WriteLine("ProduceN Run Over");
}
public void ProduceM()
{
lock (craeterM)
{
for (; m < max; m++)
{
Console.WriteLine("释放 m=" + m.ToString());
//Monitor.Pulse(craeterM);
bool isReleaseM = Monitor.Wait(craeterM);
Console.WriteLine("Consume 重新获取了createrM 的锁 " + isReleaseM.ToString());
}
}
Console.WriteLine("ProduceM Run Over");
}

public void Consume()
{
lock (createrN)
{
lock (craeterM)
{
while (m < max && n < max)
{
Console.WriteLine("接收 n=" + n.ToString() + " m=" + m.ToString());
Monitor.Pulse(craeterM);
//Monitor.Wait(craeterM);
bool isReleaseM = Monitor.Wait(craeterM, 500);
Console.WriteLine("ProduceM 重新获取了craeterM的锁 " + isReleaseM.ToString());
Monitor.Pulse(createrN);
//Monitor.Wait(createrN);
bool isReleaseN = Monitor.Wait(createrN, 500);
Console.WriteLine("ProduceN 重新获取了createrN 的锁 " + isReleaseN.ToString());
}
}
}
Console.WriteLine("Consume Run Over");
}
}
class Program
{
static void Main(string[] args)
{
MonitorClass m = new MonitorClass();
Thread tProduce = new Thread(new ThreadStart(m.ProduceN));
Thread tProduceM = new Thread(new ThreadStart(m.ProduceM));
Thread tConsume = new Thread(new ThreadStart(m.Consume));
tProduce.Start();
tProduceM.Start();
tConsume.Start();
Console.ReadLine();
}
}
}
3、介绍一下对Monitor类的一点小的看法
Monitor类从字面意思看是一个监视器,其实它的每次操作也是单独的一个线程
等于是几个线程同时工作,中间由Monitor类来协调工作先后次序、以及帮助线程间传递消息,算是个指挥官的角色
并且Monitor。Wait 方法 是有返回值的Msdn上是真样说的
如果调用由于调用方重新获取了指定对象的锁而返回,则为 true。如果未重新获取该锁,则此方法不会返回。
我的理解是,如果其他线程获取了该对象的锁并且显示的通过 Monitor.Pulse(object obj)方法进行对其它等待线程的通知返回 true
否则返回false
原因:当我不进行显示脉冲通知的时候执行结果是这样的
并且每次执行时等待500毫秒
进行通知 取消Monitor.Pulse(craeterM); 前面的注释 后的执行结果是

每次执行 Monitor..::.Wait 方法 返回的都是true
并且中间时间没有等待间隔
好像只有最后一次有
所以说Monitor。Wait 方法的返回值我们可以这样理解
如果其他线程获取了该对象的锁并且显示的通过 Monitor.Pulse(object obj)方法进行对其它等待线程的通知返回 true
否则返回false
4、根据代码执行结果分析程序的执行顺序
说着不清楚所以画了张图
大家跟着程序执行的顺序应该能够看得清楚
这张图说明了程序执行的顺序,同时也说明了 Monitor 对象是由自己一个单独的线程进行控制的,起着调节的作用
但是刚才好像还是有个问题就是
在Consume()中使用超时等待模式isReleaseM = Monitor.Wait(craeterM, 1000);时
有最后一次出现等待现象
是什么原因呢???
暂时没有搞明白。。。。
原文作者 陈晨 有兴趣的话可以一起研究
好,就到这儿了
希望大家批评斧正、、
源码 ThreadMonitorDemo2008-07-31.rar
出处:http://XuShen8314.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
个人网站:http://www.198314.com


浙公网安备 33010602011771号