C#多线程编程(2):线程的同步
2010-09-30 21:09:36 来源:WEB开发网当然这段代码最终运行的效果也和使用lock关键字来同步的效果一样。比较之下,大家会发现使用lock关键字来保持同步的差别不大:”lock (objLock){“被换成了”Monitor.Enter(objLock);”,”}”被换成了” Monitor.Exit(objLock);”。实际上如果你通过其它方式查看最终生成的IL代码,你会发现使用lock关键字的代码实际上是用 Monitor来实现的。
如下代码:
lock (objLock){
//同步代码
}
实际上是相当于:
try{
Monitor.Enter(objLock);
//同步代码
}
finally
{
Monitor.Exit(objLock);
}
我们知道在绝大多数情况下finally中的代码块一定会被执行,这样确保了即使同步代码出现了异常也仍能释放同步锁。
Monitor 类除了Enter()和Exit()方法之外,还有Wait()和Pulse()方法。Wait()方法是临时释放当前活得的锁,并使当前对象处于阻塞状态,Pulse()方法是通知处于等待状态的对象可以准备就绪了,它一会就会释放锁。下面我们利用这两个方法来完成一个协同的线程,一个线程负责随机产生数据,一个线程负责将生成的数据显示出来。下面是代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace StartThread
{
public class ThreadWaitAndPluse
{
private object lockObject;
private int number;
private Random random;
public ThreadWaitAndPluse()
{
lockObject = new object();
random = new Random();
}
//显示生成数据的线程要执行的方法
public void ThreadMethodOne()
{
Monitor.Enter(lockObject);//获取对象锁
Console.WriteLine("当前进入的线程:" + Thread.CurrentThread.GetHashCode());
for (int i = 0; i < 5; i++)
{
Monitor.Wait(lockObject);//释放对象锁,并阻止当前线程
Console.WriteLine("WaitAndPluse1:工作");
Console.WriteLine("WaitAndPluse1:得到了数据,number=" + number + ",Thread ID=" + Thread.CurrentThread.GetHashCode());
//通知其它等待锁的对象状态已经发生改变,当这个对象释放锁之后等待锁的对象将会活得锁
Monitor.Pulse(lockObject);
}
Console.WriteLine("退出当前线程:" + Thread.CurrentThread.GetHashCode());
Monitor.Exit(lockObject);//释放对象锁
}
//生成随机数据线程要执行的方法
public void ThreadMethodTwo()
{
Monitor.Enter(lockObject);//获取对象锁
Console.WriteLine("当前进入的线程:" + Thread.CurrentThread.GetHashCode());
for (int i = 0; i < 5; i++)
{
//通知其它等待锁的对象状态已经发生改变,当这个对象释放锁之后等待锁的对象将会活得锁
Monitor.Pulse(lockObject);
Console.WriteLine("WaitAndPluse2:工作");
number =random.Next(DateTime.Now.Millisecond);//生成随机数
Console.WriteLine("WaitAndPluse2:生成了数据,number=" + number + ",Thread ID=" + Thread.CurrentThread.GetHashCode());
Monitor.Wait(lockObject);//释放对象锁,并阻止当前线程
}
Console.WriteLine("退出当前线程:" + Thread.CurrentThread.GetHashCode());
Monitor.Exit(lockObject);//释放对象锁
}
public static void Main()
{
ThreadWaitAndPluse demo=new ThreadWaitAndPluse();
Thread t1 = new Thread(new ThreadStart(demo.ThreadMethodOne));
t1.Start();
Thread t2 = new Thread(new ThreadStart(demo.ThreadMethodTwo));
t2.Start();
Console.ReadLine();
}
}
}
更多精彩
赞助商链接