这篇文章介绍了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);
threadA.Name = "A";
Thread threadB = new Thread(ThreadMethod);
threadB.Name = "B";
threadA.Start();
threadB.Start();
Thread.CurrentThread.Name = "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(Thread.CurrentThread.Name + ":" + 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);
threadA.Name = "A";
Thread threadB = new Thread(ThreadMethod);
threadB.Name = "B";
threadA.Start();
threadB.Start();
Thread.CurrentThread.Name = "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(Thread.CurrentThread.Name + ":" + 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类实现线程同步的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持得得之家。
本文标题为:C#使用Monitor类实现线程同步
基础教程推荐
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- ZooKeeper的安装及部署教程 2023-01-22
- C# windows语音识别与朗读实例 2023-04-27
- C#控制台实现飞行棋小游戏 2023-04-22
- 一个读写csv文件的C#类 2022-11-06
- C# 调用WebService的方法 2023-03-09
- C#类和结构详解 2023-05-30
- C# List实现行转列的通用方案 2022-11-02
- unity实现动态排行榜 2023-04-27
- winform把Office转成PDF文件 2023-06-14