线程基础四 使用Monitor类锁定资源
2024-08-30 09:52:43
前面我们讲过了lock的用法以及竞争条件导致的错误,实际上lock关键字是Monitor类用例的一个语法糖。如果我们分解使用了lock关键字的代码,将会看到它如下面代码片段所示:
bool acquireLock = false;
try
{
Monitor.Enter(lockObject, ref acquireLock);
//Code that access resources that are protected by the lock.
}
finally
{
if (acquireLock)
{
Monitor.Exit(acquireLock);
}
}
在多线程编程中另一个常见的多线程错误被称为死锁(deadlock)。在以下例子中,将演示使用Monitor类来避免死锁,而之前描述过得lock用于创建死锁。
static void Main(string[] args)
{
object lock1 = new object();
object lock2 = new object();
new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock (lock2)
{
Thread.Sleep();
Console.WriteLine(@"Monitor.TryEnter allows not to get stuck,returning false after a specified timeout is elapsed");
if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds()))
{
Console.WriteLine("Acquired a protected resource successfully");
}
else
{
Console.WriteLine("Timeout acquiring a resource!");
}
} new Thread(() => LockTooMuch(lock1, lock2)).Start(); Console.WriteLine("-----------------------------");
lock (lock2)
{
Console.WriteLine("This will be a deadlock");
Thread.Sleep();
lock (lock1)
{
Console.WriteLine("Acquired a protected resouce successfully");
}
} }
static void LockTooMuch(object lock1, object lock2)
{
lock (lock1)
{
Thread.Sleep();
lock (lock2) ;
}
}
在这个例子中,先定义了一个LockTooMuch方法。在该方法中,我们先锁定了第一个对象,等待一秒后锁定了第二个对象。然后在另一个线程中启动该方法。最后尝试在主线程中先后锁定第二个和第一个对象。我们分为两部分,分别使用Montitor以及lock演示了如何避免死锁以及造成死锁。
首先先说说造成死锁的情况,在第二部分中,我们使用了lock关键字。通过new Thread新起的线程使得程序保持对lock1对象的锁定,等待直到lock2对象被释放。而此时主线程却又在保持对lock2对象的锁定并等待直到lock1对象被释放,但lock1却被新起的线程占用,等待lock2,因此lock1对象永远不会被释放,从而进入死锁状态。
因此,我们就可以通过第一部分的方式,采用Monitor类的TryEnter方法,该方法接受一个超时参数。如果我们不能在超市参数过期之前获取到被lock保护的资源,则该方法返回false。
最新文章
- JavaScript(七)——视频插入
- HighCharts学习笔记(二)HighCharts结构及详细配置
- 重构第17天提取父类(Extract SuperClass)
- Ajax 用法
- [转] Android自动测试之monkeyrunner工具(二)
- 第二次作业第2题_JH
- Page Cache buffer Cache
- 场景:A-->;B-->;C 跳转到C时,要关掉B的处理方法
- 关于java线程中stop interrupt daemon wait notify
- Golang随机数生成
- Python3 tkinter基础 Scale orient 横竖 resolution单步步长 length 长度 tickinterval 指示刻度
- Python项目--Scrapy框架(一)
- Python3.5 MySQL 数据库连接
- 云ci自动构建实例 最佳实践
- 使用maven将GitHub上项目打包作为依赖添加
- delphi xe----操作mongoDB驱动,TMongoWire(Delphi MongoDB Driver)
- python进程与线程介绍
- BZOJ2120:数颜色(莫队版)
- 【Android小项目】找不同,改编自&;quot;寻找房祖名&;quot;的一款开源小应用。
- 跳石头(codevs 4768)