锁、C#中Monitor和Lock以及区别
1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit())。
2.Monitor的常用属性和方法:
Enter(Object) 在指定对象上获取排他锁。
Exit(Object) 释放指定对象上的排他锁。
IsEntered 确定当前线程是否保留指定对象锁。
Pulse 通知等待队列中的线程锁定对象状态的更改。
PulseAll 通知所有的等待线程对象状态的更改。
TryEnter(Object) 试图获取指定对象的排他锁。
TryEnter(Object, Boolean) 尝试获取指定对象上的排他锁,并自动设置一个值,指示是否得到了该锁。
Wait(Object) 释放对象上的锁并阻止当前线程,直到它重新获取该锁。
Lock关键字
1.Lock关键字实际上是一个语法糖,它将Monitor对象进行封装,给object加上一个互斥锁,A进程进入此代码段时,会给object对象加上互斥锁,此时其他B进程进入此代码段时检查object对象是否有锁?如果有锁则继续等待A进程运行完该代码段并且解锁object对象之后,B进程才能够获取object对象为其加上锁,访问代码段。
2.Lock关键字封装的Monitor对象结构如下:
try
{
Monitor.Enter(obj);
dosomething();
}
catch(Exception ex)
{ }
finally
{
Monitor.Exit(obj);
}
3.锁定的对象应该声明为private static object obj = new object();尽量别用公共变量和字符串、this、值类型。
Monitor和Lock的区别
1.Lock是Monitor的语法糖。
2.Lock只能针对引用类型加锁。
3.(使用 Monitor 锁定对象(即引用类型)而不是值类型。)。
4.Monitor还有其他的一些功能。
class Program
{
private static object obj = new object();
public void LockSomething()
{
lock (obj)
{
dosomething();
}
}
public void MonitorSomeThing()
{
try
{
Monitor.Enter(obj);
dosomething();
}
catch(Exception ex)
{ }
finally
{
Monitor.Exit(obj);
}
} public void dosomething()
{
//做具体的事情
}
}
Monitor 类通过向单个线程授予对象锁来控制对对象的访问。对象锁提供限制访问代码块(通常称为临界区)的能力。当一个线程拥有对象的锁时,其他任何线程都不能获取该锁。还可以使用 Monitor 来确保不会允许其他任何线程访问正在由锁的所有者执行的应用程序代码节,除非另一个线程正在使用其他的锁定对象执行该代码。
Monitor 具有以下功能:
它根据需要与某个对象相关联。
它是未绑定的,也就是说可以直接从任何上下文调用它。
不能创建 Monitor 类的实例。
将为每个同步对象来维护以下信息:
对当前持有锁的线程的引用。
对就绪队列的引用,它包含准备获取锁的线程。
对等待队列的引用,它包含正在等待锁定对象状态变化通知的线程。
下表描述了访问同步对象的线程可以采取的操作:
操作
说明
Enter, TryEnter
获取对象锁。此操作同样会标记临界区的开头。其他任何线程都不能进入临界区,除非它使用其他锁定对象执行临界区中的指令。
释放对象上的锁以便允许其他线程锁定和访问该对象。在其他线程访问对象时,调用线程将等待。脉冲信号用于通知等待线程有关对象状态的更改。
向一个或多个等待线程发送信号。该信号通知等待线程锁定对象的状态已更改,并且锁的所有者准备释放该锁。等待线程被放置在对象的就绪队列中以便它可以最后接收对象锁。一旦线程拥有了锁,它就可以检查对象的新状态以查看是否达到所需状态。
释放对象上的锁。此操作还标记受锁定对象保护的临界区的结尾。
使用 Enter 和 Exit 方法标记临界区的开头和结尾。如果临界区是一个连续指令集,则由 Enter 方法获取的锁将保证只有一个线程可以使用锁定对象执行所包含的代码。在这种情况下,建议您将这些指令放在 try 块中,并将 Exit 指令放在 finally 块中。此功能通常用于同步对类的静态或实例方法的访问。如果实例方法需要同步线程访问,则它将使用当前实例作为要锁定的对象调用 Enter 和对应的 Exit 方法。由于只能有一个线程持有当前实例上的锁,因此该方法一次只能由一个线程来执行。静态方法是使用当前实例的 Type 作为锁定对象以类似的方式来保护的。Enter 和 Exit 方法提供的功能与 C# lock 语句(在 Visual Basic 中为 SyncLock)提供的功能相同,区别在于 lock 和 SyncLock 以 try…finally 块(在 Visual Basic 中为 Try…Finally)来包装 Exit 方法,以确保释放监视器。
如果临界区跨越整个方法,则可以通过将 System.Runtime.CompilerServices.MethodImplAttribute 放置在方法上并在 MethodImplAttribute 的构造函数中指定 Synchronized 值来实现上述锁定功能。使用该属性后就不需要 Enter 和 Exit 语句了。请注意,该属性将使当前线程持有锁,直到方法返回;如果可以更早释放锁,则使用 Monitor 类或 C#lock 语句而不是该属性。
尽管锁定和释放给定对象的 Enter 和 Exit 语句可以跨越成员或类的边界或同时跨越两者的边界,但并不推荐这样做。
当选择要同步的对象时,应只锁定私有或内部对象。锁定外部对象可能导致死锁,这是因为不相关的代码可能会出于不同的目的而选择锁定相同的对象。
- 以上来自MSDN、
- @陈卧龙的博客
锁、C#中Monitor和Lock以及区别的更多相关文章
- C#知识点总结系列:4、C#中Monitor和Lock以及区别
Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...
- C#中Monitor和Lock以及区别
Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...
- C#知识点总结:Monitor和Lock以及区别
Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...
- Monitor和Lock以及区别
1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁 ...
- Java中synchronized和Lock的区别
synchronized和Lock的区别synchronize锁对象可以是任意对象,由于监视器方法必须要拥有锁对象那么任意对象都可以调用的方法所以将其抽取到Object类中去定义监视器方法这样锁对象和 ...
- Java ReentrantLock中tryLock与lock的区别(非公平锁与公平锁)
设置同步状态,利用CAS操作. // CAS操作:如果当前状态值等于期望值,则自动将同步状态设置为给定的更新值 protected final boolean compareAndSetState(i ...
- C#中Monitor对象与Lock关键字的区别分析
这篇文章主要介绍了C#中Monitor对象与Lock关键字的区别,需要的朋友可以参考下 Monitor对象 1.Monitor.Enter(object)方法是获取 锁,Monitor.Exit(ob ...
- 转:C#中Monitor对象与Lock关键字的区别分析
Monitor对象1.Monitor.Enter(object)方法是获取 锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...
- 第十三节:实际开发中使用最多的监视锁Monitor、lock语法糖的扩展、混合锁的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)
一. 监视锁(Monitor和lock) 1. Monitor类,限定线程个数的一把锁,两个核心方法: Enter:锁住某个资源. Exit:退出某一个资源. 测试案例:开启5个线程同时对一个变量进行 ...
随机推荐
- (后端)异常不仅仅是try/catch
前言 编程时我们往往拿到的是业务流程正确的业务说明文档或规范,但实际开发中却布满荆棘和例外情况,而这些例外中包含业务用例的例外,也包含技术上的例外.对于业务用例的例外我们别无它法,必须要求实施人员与 ...
- [20180625]oradebug peek 2.txt
[20180625]oradebug peek 2.txt --//上个星期演示了oradebug peek查看内存数据块的情况,oradebug peek {address} length 1,最后 ...
- [20180627]truncate table的另类恢复.txt
[20180627]truncate table的另类恢复.txt --//前几天看链接http://www.xifenfei.com/2018/06/truncate-table-recovery. ...
- javascript避免dom事件重复触发
/** * 为指定控件添加限制性事件, 该事件在触发之后, 会被移除, 并在指定的时间间隔后, 重新绑定, 适用于避免控件事件被误操作重复触发的场景 * @param {String} domID 要 ...
- HTML 5 <input> list 属性
定义和用法 list 属性引用数据列表,其中包含输入字段的预定义选项. 可以用来做关联搜素
- Gnome增加消息提醒extension ( Fedora 28 )
访问 https://extensions.gnome.org/ 网站(注意:需要安装 chrome-gnome-shell rpm 包来使得系统能与Web Browser进行通信) 安装插件: n ...
- Windows服务器搭建Redis
1.下载安装Redis https://github.com/MicrosoftArchive/redis/releases 可以下载安装版(.msi)也可以下载解压版(.zip). 我直接下载的安装 ...
- Centos7系统如何不重启系统识别新添加的硬盘?
今天在系统开机后插入三块硬盘,结果没有一块硬盘被系统识别到.后来找到了方法. echo "- - -" > /sys/class/scsi_host/host0/scan 上 ...
- Vue、Vuex+Cookie 实现自动登陆 。
概述 1.自动登陆实现思路. 2.vuex + cookie 多标签页状态保持. 自动登陆的需求: 1.登陆时勾选自动登陆,退出登陆或登陆到期后再次登陆后自动填写表单(记住密码)或访问登陆页自动登陆. ...
- Swift中的反射
原文:http://www.cocoachina.com/applenews/devnews/2014/0623/8923.html Swift 事实上是支持反射的.只是功能略弱. 本文介绍主要的反射 ...