线程基础四 使用Monitor类锁定资源
前面我们讲过了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。
线程基础四 使用Monitor类锁定资源的更多相关文章
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- C#当中的多线程_线程基础
前言 最近工作不是很忙,想把买了很久了的<C#多线程编程实战>看完,所以索性把每一章的重点记录一下,方便以后回忆. 第1章 线程基础 1.创建一个线程 using System; usin ...
- C#多线程编程系列(二)- 线程基础
目录 C#多线程编程系列(二)- 线程基础 1.1 简介 1.2 创建线程 1.3 暂停线程 1.4 线程等待 1.5 终止线程 1.6 检测线程状态 1.7 线程优先级 1.8 前台线程和后台线程 ...
- C#多线程编程实战(一):线程基础
1.1 简介 为了防止一个应用程序控制CPU而导致其他应用程序和操作系统本身永远被挂起这一可能情况,操作系统不得不使用某种方式将物理计算分割为一些虚拟的进程,并给予每个执行程序一定量的计算能力.此外操 ...
- Thread锁 Monitor类、Lock关键字和Mutex类
Monitor 类锁定一个对象 当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可 ...
- C# 线程(四):生产者和消费者
From : http://kb.cnblogs.com/page/42530/ 前面说过,每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时 ...
- Android多线程研究(1)——线程基础及源代码剖析
从今天起我们来看一下Android中的多线程的知识,Android入门easy,可是要完毕一个完好的产品却不easy,让我们从线程開始一步步深入Android内部. 一.线程基础回想 package ...
- Android多线程研究(1)——线程基础及源码剖析
从今天起我们来看一下Android中的多线程的知识,Android入门容易,但是要完成一个完善的产品却不容易,让我们从线程开始一步步深入Android内部. 一.线程基础回顾 package com. ...
- C# 线程同步之排它锁/Monitor监视器类
一.Monitor类说明,提供同步访问对象的机制. 1.位于System.Threading命名空间下,mscorlib.dll程序集中. 2.Monitor通过获取和释放排它锁的方式实现多线程的同步 ...
随机推荐
- Qt 线程初识别
Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里. 这里我使用的是继承的方法使用线程花一个"复杂" ...
- ZT 父子进程共享文件描述符
转贴自倒霉熊的博客 [linux学习笔记-2]父子进程共享文件描述符 (2009-03-02 23:03:17) 转载▼ 标签: 学习 linux 子进程 文件描述符 杂谈 分类: 学习 #inclu ...
- GCO团队合作
队名:GCO 队员: B20150304116谢冰媛 (组长) B20150304401王粲 B20150304115钟玺琛 B20150304226梁天海 ...
- 「C基础」位运算
0. 原码.补码.反码 初学者只做了解即可 见 张子秋的博客 无论正负数,在内存中存储的都是补码 正数:反码 == 原码 == 补码 负数:反码 == ~原码 补码 == 反码+1 1. & ...
- 让免费版MarkdownPad2使用Pro版本的功能
让免费版MarkdownPad2使用Pro版本的功能 找到配置文件 启用Markdown扩展模式 Markdown处理器:Github风格 语法检查设置 自动保存设置 找到配置文件 一般在用户的数据目 ...
- 牛客国庆集训派对Day2 F、平衡二叉树 【构造+记忆化搜索】
任意门:https://www.nowcoder.com/acm/contest/202/F 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 1048576K,其他语言2097152K6 ...
- MariaDB修改端口号
修改端口号 打开my.ini文件
- sqlite配置下载安装教程
安装教程 第一步: 首先去官网下载:https://www.sqlite.org/download.html 或直接下载:https://github.com/weibanggang/sqlite 下 ...
- Android学习笔记_13_网络通信之多个上传文件
一.获取HTTP协议: 建立一个Web项目,建立一个如下所示的jsp界面,用IE捕获表单提交信息. <%@ page language="java" contentType= ...
- 利用css transition属性实现一个带动画显隐的微信小程序部件
我们先来看效果图 像这样的一个带过渡效果的小部件在我们实际开发中的应用几率还是比较大的,但是在开发微信小程序的过程中可能有的小伙伴发现transition这个属性它不好使(下面说明)所以我们这个时候会 ...