Lock VS Monitor

介绍

介绍


对开发人员来说,处理关键代码部分的多线程应用程序是非常重要的。

Monitor和lock是c#语言中多线程应用程序中提供线程安全的方法(lock关键字的本质就是对Monitor的封装)。两者都提供了一种机制来确保只有一个线程同时执行代码,以避免代码功能被其他线程中断

640?wx_fmt=png

c#中 Lock关键字确保一个线程同时执行一段代码。lock关键字确保一个线程不进入代码的锁定区,而另一个线程在锁定区内。

Lock关键字是Monitor的“快捷方式”。

namespace Monitor_Lock  	
{  	class Program  	{  	static readonly object _object = new object();  	static void TestLock()  	{  	lock (_object)  	{  	Thread.Sleep(100);  	Console.WriteLine(Environment.TickCount);  	}  	}  	static void Main(string[] args)      	{  	for (int i = 0; i < 10; i++)  	{  	ThreadStart start = new ThreadStart(TestLock);  	new Thread(start).Start();  	}  	Console.ReadLine();  	}  	}  	
}

输出:

640?wx_fmt=png

这里我们看到一个静态方法“TestLock”,它在对象上使用lock语句。在新线程上多次调用TestLock方法时,每次调用该方法都会访问该锁的对象是否释放。

Main方法创建十个新线程,然后在每个线程上开始调用。方法TestLock被调用十次,但是Environment.TickCount计数器显示受保护的方法区域是按顺序执行的,大约相隔100毫秒。

如果另一个线程试图进入一个锁定的代码,它将等待,阻塞,直到对象被释放。


lock关键字通过获取给定对象的互斥锁,将语句块标记为一个临界段,执行语句,然后释放锁,


Monitor


Monitor提供了一种同步对象访问的机制。它可以通过获取一个重要的锁来实现,这样一次只有一个线程可以进入给定的代码段。Monitor与lock没有什么不同,但是Monitor类对试图访问相同代码锁的各个线程的同步提供了更多的控制。


使用Monitor可以确保不允许任何其他线程访问锁所有者正在执行的应用程序代码段,除非其他线程使用不同的锁定对象执行代码。


Monitor类有以下方法通过获取和释放锁来同步访问代码的某个区域


Enter(Object)

在指定对象上获取排他锁。

Enter(Object, Boolean)

获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

Exit(Object)

释放指定对象上的排他锁。

IsEntered(Object)

确定当前线程是否保留指定对象锁。

Pulse(Object)

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

PulseAll(Object)

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

TryEnter(Object, TimeSpan, Boolean)

在指定的一段时间内尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获得了该锁。

TryEnter(Object, Int32, Boolean)

在指定的毫秒数内尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

TryEnter(Object, TimeSpan)

在指定的时间内尝试获取指定对象上的排他锁。

TryEnter(Object, Boolean)

尝试获取指定对象上的排他锁,并自动设置一个值,指示是否获取了该锁。

TryEnter(Object)

尝试获取指定对象的排他锁。

TryEnter(Object, Int32)

在指定的毫秒数内尝试获取指定对象上的排他锁。

Wait(Object, Int32, Boolean)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。 此方法还指定是否在等待之前退出上下文的同步域(如果处于同步上下文中的话)然后重新获取该同步域。

Wait(Object)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。

Wait(Object, Int32)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。

Wait(Object, TimeSpan)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。

Wait(Object, TimeSpan, Boolean)

释放对象上的锁并阻止当前线程,直到它重新获取该锁。 如果已用指定的超时时间间隔,则线程进入就绪队列。 可以在等待之前退出同步上下文的同步域,随后重新获取该域。

Monitor锁定对象(即引用类型),而不是值类型。虽然您可以传递一个值类型来进入和退出,但是对于每个调用,它都是单独装箱的。

Wait在锁被持有并等待被通知时释放锁。当Wait被通知时,它返回并再次获得锁。Pulse和PulseAll都为等待队列中的下一个线程的开始发出信号。

下面是使用Monitor的语法。

try  	
{  	int x = 1;  	Monitor.Enter(x);  	try  	{  	// Code that needs to be protected by the monitor.  	}  	finally  	{  	Monitor.Exit(x);  	}  	
}  	
catch (SynchronizationLockException SyncEx)  	
{  	Console.WriteLine("A SynchronizationLockException occurred. Message:");  	Console.WriteLine(SyncEx.Message);  	
}

简单例子:

namespace Monitor_Lock  	
{  	class Program  	{  	static readonly object _object = new object();  	public static void PrintNumbers()  	{  	Monitor.Enter(_object);  	try  	{  	for (int i = 0; i < 5; i++)  	{  	Thread.Sleep(100);  	Console.Write(i + ",");  	}  	Console.WriteLine();  	}  	finally  	{  	Monitor.Exit(_object);  	}  	}  	static void TestLock()  	{  	lock (_object)  	{  	Thread.Sleep(100);  	Console.WriteLine(Environment.TickCount);  	}  	}  	static void Main(string[] args)      	{  	Thread[] Threads = new Thread[3];  	for (int i = 0; i < 3; i++)  	{  	Threads[i] = new Thread(new ThreadStart(PrintNumbers));  	Threads[i].Name = "Child " + i;  	}  	foreach (Thread t in Threads)  	t.Start();  	Console.ReadLine();  	}  	}  	
}

输出:

640?wx_fmt=png

在c# 4.0中,Monitor.Enter(_object,ref _lockTaken)重载函数获取一个独占锁和指定的对象,并自动设置一个值,该值指示锁是否被获取。

640?wx_fmt=png


class Program  	
{  	static readonly object _object = new object();  	public static void PrintNumbers()  	{  	Boolean _lockTaken = false;  	Monitor.Enter(_object,ref _lockTaken);  	try  	{  	for (int i = 0; i < 5; i++)  	{  	Thread.Sleep(100);  	Console.Write(i + ",");  	}  	Console.WriteLine();  	}  	finally  	{  	if (_lockTaken)  	{  	Monitor.Exit(_object);  	}  	}  	}	
}

与lock等价的Monitor实现

Monitor.Enter(object);	
try	
{	// Your code here...	
}	
finally	
{	Monitor.Exit(object);	
}


结论

Monitor类是一个静态类,不能创建它的实例。

Monitor类对象使用 Monitor.TryEnter, and Monitor.Exit 方法。一旦锁定了代码区域,就可以使用 Monitor.Wait, Monitor.Pulse, and Monitor.PulseAll 等方法。

Lock和monitor在多线程中基本上用于相同的目的,Monitor的不同之处在于,当我们希望对运行特定代码段的多个线程的同步进行更多控制时更有效

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/314772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员修神之路--做好分库分表其实很难之二

菜菜哥&#xff0c;上次听你给我讲了分库的情况后&#xff0c;我明白了很多&#xff0c;能再给我讲讲分表吗有收获就好&#xff0c;分表其实有很多情况和分库类似还有不一样的情况吗&#xff1f;有呀&#xff0c;本来数据库和表是不同层面的东西&#xff0c;肯定有差异那你给讲…

2021牛客暑期多校训练营3 B Black and white 最小生成树 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 对于每个数的位置(i,j)(i,j)(i,j)&#xff0c;如果将这个位置染黑&#xff0c;那么我们连一个i−>jni->jni−>jn的边&#xff0c;可以发现我们的操作不影响连通性。如果想要全部染…

关于WinForms的跨显示器DPI自适应

点击上方蓝字关注“汪宇杰博客”导语WinForms 是运行在Windows上的传统.NET桌面应用技术框架。由于历史原因&#xff0c;它对高DPI以及跨不同DPI屏幕的支持有些问题&#xff0c;本文将探索尽可能的解决方案。Windows 的“黑历史”Windows 系统的默认DPI&#xff08;更确切的说法…

.NET开发框架(九)-NLB网络负载平衡配置实战(视频)

&#xff08;NLB配置实战教程-有声视频-第二节&#xff09;请持续关注公众号&#xff0c;第三节&#xff08;NLBARR)正在录制中~第六章IIS负载均衡教程&#xff0c;至今共有37人参与学习尚未学习第六章-IIS负载均衡-视频教程的童靴&#xff0c;赶紧跟上进度&#xff0c;别掉队了…

C#各版本新增加功能

本系列文章主要整理并介绍 C# 各版本的新增功能。C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布&#xff0c;但是当前处于预览状态。预计在2019年9月正式发布。目前提供以下功能可供试用&#xff1a;Readonly 成员默认接口成员【*重要&#xff0c;…

宣告推出.NET Core 3.0 Preview 7

译&#xff1a;艾心0626今天&#xff0c;我们宣布推出.NET Core 3.0 Preview 7。我们已经从创建新特性阶段过渡到了完善版本阶段。对于接下来的预览版&#xff0c;我们将把重点放在质量(改进)上。在Windows&#xff0c;macOS和Linux上下载.NET Core 3.0 Preview 7。.NET Core 3…

基于Masstransit实现Eventbus的功能

Masstransit 是一个非常优秀的基于消息进行通信的分布式应用程序框架&#xff0c;详情参考官网。在介绍AA.ServiceBus之前&#xff0c;先介绍下几个概念.分布式分布式系统如何定义&#xff1f;这里引用一下Distributed Systems Concepts and Design(Third Edition)中的一句话&a…

微软解释为什么Rust是系统编程的最佳选择

上周&#xff0c;MSRC&#xff08;微软安全响应中心&#xff09;透露出拥抱 Rust 的打算&#xff0c;随后他们将这个话题扩展为一个系列&#xff0c;进一步阐述了使用安全的系统编程语言的的必要性&#xff0c;以及选择 Rust 的原因。在该系列最新一篇文章中&#xff0c;MSRC 团…

你可能不知道的Docker资源限制

本篇内容涉及Docker的内存与CPU限制&#xff0c;可以用于在实际开发中为指定容器设置限制最大使用的资源量&#xff0c;预计阅读时间为5分钟。01—What is 资源限制&#xff1f;默认情况下&#xff0c;容器是没有资源限制的&#xff0c;它会尽可能地使用宿主机能够分配给它的资…

东南亚的IT公司,我劝你善良!

来源公众号&#xff1a;半佛仙人&#xff08;ID&#xff1a;banfoSB&#xff09;“真的救我一条‘狗命’&#xff0c;可以吗&#xff0c;谢谢您了&#xff0c;我真的撑不住了。”5月3日&#xff0c;小巴在朋友圈看到这条信息&#xff0c;附着一张长图&#xff0c;定位&#xff…

小白开学Asp.Net Core 《九》

小白开学Asp.Net Core 《九》 — — 前端篇&#xff08;不务正业&#xff09;在《小白开学Asp.Net Core 三》中使用了X-admin 2.x 和 Layui将管理后端的界面重新布局了&#xff0c;里面简单的介绍了layui table 的使用以及页面table所需的数据做了简单的封装。今天扩展学习下。…

.net持续集成sonarqube篇之sonarqube安装与基本配置

Sonarqube下载与安装Sonarqube下载地址是:https://www.sonarqube.org/downloads/下载版本有两个,一个是长期支持版,另一个是最新版,此处安装的是最新版,目前版本是7.3,下载的时候点击醒目的蓝色按钮即可(此时下载的是社区版),下面有三个无底色按钮下载链接,分别对应的是开发者版…

Codeforces Round #296 (Div. 1) D. Fuzzy Search FFT匹配字符串

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; n,m,k≤2e5n,m,k\le2e5n,m,k≤2e5 思路&#xff1a; 直接考虑fftfftfft来匹配字符串。 由于kkk是给定的&#xff0c;所以难度低了很多&#xff0c;普通的字符串匹配不能处理这种可以范围相等的情况&#xf…

迁移 WinForm 应用从 dotnet framework 到 dotnetcore3.0

迁移 WinForm 应用从 dotnet framework 到 dotnetcore3.0Intro微软从 dotnetcore3.0 开始已经开始支持 wpf 以及 winform 的开发&#xff0c;dotnet core 3.0 preview7 已经发布&#xff0c;官方称已经可以准备上生产了 Production Ready迁移这篇WPF的迁移还是比较不错的&#…

HDU - 6992 Lawn of the Dead 线段树 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一张n∗mn*mn∗m的图&#xff0c;其中有kkk个点不能走&#xff0c;你只能向下和向右走&#xff0c;问你能到达多少点。 n,m,k≤1e5n,m,k\le1e5n,m,k≤1e5 思路&#xff1a; 可以发现每个点如果其左边和…

EZNEW.NET开发框架100%重磅开源

EZNEW.NET是一套基于领域驱动开发(DDD)为指导思想的企业级项目通用开发框架。通过将当前主流的开发技术和最佳的开发实践相结合&#xff0c;将开发中常见且严重影响开发效率的繁琐技术细节进行了模块化的封装&#xff0c;让开发人员能将更多更多精力聚焦在系统业务的分析中去&a…

黑暗爆炸OJ 3028. 食物 生成函数

传送门 文章目录题意&#xff1a;思考题意&#xff1a; 思考 考虑将每个条件转换成生成函数&#xff1a; (1)f1(x)1x2...11−x2(1)f_1(x)1x^2...\frac{1}{1-x^2}(1)f1​(x)1x2...1−x21​ (2)f2(x)1x1−x21−x(2)f_2(x)1x\frac{1-x^2}{1-x}(2)f2​(x)1x1−x1−x2​ (3)f3(x)1x…

「Azure」数据分析师有理由爱Azure之一-Azure能带给我们什么?

前面我们以相同的方式从数据分析师的视角介绍了Sqlserver&#xff0c;本系列亦同样地延续下去&#xff0c;同样是挖掘数据分析师值得使用的Azure云平台的功能。因云平台功能太多&#xff0c;笔者所接触的面也十分有限&#xff0c;有更专业的读者欢迎补充。对云服务的一点点小认…

POJ - 3734 Blocks 指数生成函数

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 一段长度为nnn的序列&#xff0c;你有红黄蓝绿四种颜色的砖块&#xff0c;问你铺砖的方案数&#xff0c;每块砖长度为111&#xff0c;其中红黄颜色个数必须为偶数。 思路&#xff1a; 考虑多重集合排列数&…

理想化的DevOps团队里只需要有Dev就够了?

&#xff08;图片来源于网络&#xff09;几天前&#xff0c;本公众号发布的一篇译文列举了9种DevOps团队结构适用类型与7种反型&#xff08;点击查看原文&#xff09;。文章转发到朋友圈之后&#xff0c;很多DevOps同行留言&#xff08;吐槽&#xff09;了自己团队的现状&#…