C#使用Monitor类实现线程同步

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C#使⽤Monitor类实现线程同步
⼀、简介
Lock关键字是Monitor的⼀种替换⽤法,lock在IL代码中会被翻译成Monitor.
lock (obj)
{
//代码段
}
//就等同于
Monitor.Enter(obj);
//代码段
Monitor.Exit(obj);
Monitor的常⽤属性和⽅法:
Enter(Object) 在指定对象上获取排他锁。

Exit(Object) 释放指定对象上的排他锁。

Pulse 通知等待队列中的线程锁定对象状态的更改。

PulseAll 通知所有的等待线程对象状态的更改。

TryEnter(Object) 试图获取指定对象的排他锁。

TryEnter(Object, Boolean) 尝试获取指定对象上的排他锁,并⾃动设置⼀个值,指⽰是否得到了该锁。

Wait(Object) 释放对象上的锁并阻⽌当前线程,直到它重新获取该锁。

常⽤的⽅法有两个
Monitor.Enter(object)⽅法是获取锁
Monitor.Exit(object)⽅法是释放锁
这就是Monitor最常⽤的两个⽅法,在使⽤过程中为了避免获取锁之后因为异常,致锁⽆法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit())。

⼆、代码
1.Enter(Object)案例
Enter(Object)的⽤法很简单,看代码
class Program
{
static void Main(string[] args)
{
Thread threadA = new Thread(ThreadMethod);
= "A";
Thread threadB = new Thread(ThreadMethod);
= "B";
threadA.Start();
threadB.Start();
= "C";
ThreadMethod();
Console.ReadKey();
}
static object obj = new object();
public static void ThreadMethod()
{
Monitor.Enter(obj); //Monitor.Enter(obj) 鎖定对象
try
{
for (int i = 1; i <= 10; i++)
{
Console.Write( + ":" + i + "\t");
}
Console.WriteLine();
}
catch (Exception ex)
{
}
finally
{
Monitor.Exit(obj); // Monitor.Exit(obj); 释放鎖定对象
}
}
}
执⾏结果:
2.TryEnter(Object)和TryEnter()案例
TryEnter(Object)和TryEnter()⽅法在尝试获取⼀个对象上的显式锁⽅⾯和 Enter()⽅法类似。

然⽽,它不像Enter()⽅法那样会阻塞执⾏。

如果线程成功进⼊关键区域那么TryEnter()⽅法会返回true. 和试图获取指定对象的排他锁。

看下⾯代码演⽰:
class Program
{
static void Main(string[] args)
{
Thread threadA = new Thread(ThreadMethod);
= "A";
Thread threadB = new Thread(ThreadMethod);
= "B";
threadA.Start();
threadB.Start();
= "C";
ThreadMethod();
Console.ReadKey();
}
static object obj = new object();
public static void ThreadMethod()
{
bool flag = Monitor.TryEnter(obj, 1000);
//设置1S的超时时间,如果在1S之内没有获得同步锁,则返回false
//上⾯的代码设置了锁定超时时间为1秒,也就是说:
//如果在1秒中后,lockObj还未被解锁,TryEntry⽅法就会返回false,如果在1秒之内,lockObj被解锁,TryEntry返回true。

我们可以使⽤这种⽅法来避免死锁 try
{
if (flag)
{
for (int i = 1; i <= 10; i++)
{
Console.Write( + ":" + i + "\t");
}
Console.WriteLine();
}
}
catch (Exception ex)
{
}
finally
{
if (flag)
Monitor.Exit(obj); // Monitor.Exit(obj); 释放鎖定对象
}
}
}
执⾏结果:
通过Monitor.TryEnter(monster, 1000),该⽅法也能够避免死锁的发⽣,我们上⾯的例⼦⽤到的是该⽅法的重
载,Monitor.TryEnter(Object,Int32)。

三、总结
为了能避免多线程死锁的发⽣,尽量⽤TryEnter(Object)和TryEnter()⽅法在尝试获取⼀个对象上的显式锁。

到此这篇关于C#使⽤Monitor类实现线程同步的⽂章就介绍到这了。

希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档