多线程同步_Monitor

时间:2024-11-29 08:07:43

多线程一直在学习和理解中......

Monitor类是多线程中用以实现同步的一种技术,主要是同一进程内多线程间的同步技术。
Monitor类中有以下几个方法需要注意:
Monitor.Enter(object obj)方法,其意义相当于Lock(obj);
Monitor.Exit(object obj)方法,意思是释放被锁的对象
Monitor.Wait(object obj)方法,释放被锁的对象,并阻塞当前线程,等待其他线程通知(Pulse)再次获得锁 (个人理解 当前线程 锁 自己也阻塞了 要其他线程唤醒) Monitor.Pulse(object obj)方法,通知等待加锁obj的线程解除阻塞,obj对象状态已经改变(个人理解 唤醒锁住线程 这样锁住线程继续执行 当前方法也继续执行)
 

注意的是:这两个方法是成对出现,通常使用在Enter,Exit之间。也可以用lock代替

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var td = new ThredDemo(); Thread trOne = new Thread(new ParameterizedThreadStart(td.TrOne));
Thread trTwo = new Thread(new ParameterizedThreadStart(td.TrTwo)); //trOne启动线程
trOne.Name = "trOne";
trOne.Start(trOne.Name); //线程睡眠(相当于不参与cpu时间调度,通俗就是卡1000毫秒数)
Thread.Sleep(); //trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name); Console.Read();
}
} class ThredDemo
{
public List<int> obj;
int i = ; public ThredDemo()
{
obj = new List<int>();
} public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj); Console.WriteLine("");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj); Console.WriteLine("");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i); i++;
Monitor.Pulse(obj);
Console.WriteLine(""); //TrOne进入等待
Monitor.Wait(obj);
Monitor.Exit(obj);
Console.WriteLine("");
} public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("");
i++; //释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj); Console.WriteLine(""); Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i); //释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG
Monitor.Pulse(obj); -----标记
Console.WriteLine("");
}
}
}
}

为了方便理解自己加入输入查看效果 .

结果:

多线程同步_Monitor

如果我把 TrTwo方法改下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading; namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var td = new ThredDemo(); Thread trOne = new Thread(new ParameterizedThreadStart(td.TrOne));
Thread trTwo = new Thread(new ParameterizedThreadStart(td.TrTwo)); //trOne启动线程
trOne.Name = "trOne";
trOne.Start(trOne.Name); //线程睡眠(相当于不参与cpu时间调度,通俗就是卡1000毫秒数)
Thread.Sleep(); //trTwo启动线程
trTwo.Name = "trTwo";
trTwo.Start(trTwo.Name); Console.Read();
}
} class ThredDemo
{
public List<int> obj;
int i = ; public ThredDemo()
{
obj = new List<int>();
} public void TrOne(object thredName)
{
//相当于lock 参考TrTwo
Monitor.Enter(obj); Console.WriteLine("");
// TrOne释放对象上的锁并阻止当前线程这个时候TrTwo启动并进入临界区
Monitor.Wait(obj); Console.WriteLine("");
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(),i); i++;
Monitor.Pulse(obj);
Console.WriteLine(""); //TrOne进入等待 1分钟后 注意的是
// 如果指定的超时间隔已过,则线程进入就绪队列。
Monitor.Wait(obj,);
Monitor.Exit(obj);
Console.WriteLine("");
} public void TrTwo(object thredName)
{
lock (obj)
{
//TrTwo通过Wait 释放进入 这个时候TrOne阻塞i的值++
Console.WriteLine("");
i++; //释放等待的(Wait)的线程 并马上自己阻塞等待TrOne Pulse
Monitor.Pulse(obj); Console.WriteLine(""); Monitor.Wait(obj);
Console.WriteLine("线程{0}正在执行......i的值{1}", thredName.ToString(), i); //释放 这样console输出的4一定在7的后面 因为TrOne阻塞需要TrTwo释放 当前前提是程序无BUG // Monitor.Pulse(obj);
Console.WriteLine("");
}
Console.WriteLine("");
}
}
}

把Monitor.Pulse(obj);注释掉了 TrOne方法 Monitor.Wait(obj,60000);

运行后 4要等一分钟才输出 原因是 TrTwo方法没有释放 。

个人学习查看过程是 打印输出顺序查看执行过程 这样方便自己理解。

附加线程学习资料(来自博客园 )

逆时针の风  http://www.cnblogs.com/JimmyZheng/archive/2012/06/10/2543143.html

还有一线码农相对 逆时针の风 通俗懂一点

http://www.cnblogs.com/huangxincheng/category/362940.html

以及 多线程同步_Monitor 黑树

http://www.cnblogs.com/maitian-lf/p/3678128.html

http://www.cnblogs.com/maitian-lf/p/3672390.html