标签:
以下内容有错误请指正,为个人理解和经验。
c#提供三种互斥Monitor类、Lock和Mutex类,他们的区别和使用方法如下:
一、Lock类
名叫“临界区”,为Monitor的封装版,用于多线程,对单线程无用,即支持在同一个线程内多次调用lock锁定同一个目标。
用法
lock (this) { //执行代码 }
效果为在多个线程内调用同一个函数时,函数内部使用锁定方法,可以让线程进行“排队”等候,直到lock结束为止,然后其他函数才能排队进入下一个执行代码。
等待为无限等待,直到占用被释放,否则线程一直阻塞。
注意事项:不建议锁定Public对象(含this,typeof(Type),"字符串"),别和上面的例子一样使用this,强烈不推荐,因为如果lock了自己的同时,可能还存在外部有锁定该对象的可能,造成同一个对象被多个函数内部锁定,可能影响效率。建议如下使用
private object obj = new object(); public void Test() { lock (obj) { //执行代码 } }
二、Monitor类
和Lock效果一致,使用方法不同
private object obj = new object(); public void Test() { if (System.Threading.Monitor.TryEnter(obj, 1000))//排队等待1秒 { //执行代码 System.Threading.Monitor.Exit(obj);//退出 } else { //排队等不到,就不等了 } }
可以看出,区别是增加了时间,也就是如果排队不耐烦了,可以不等了,而离开队伍,对此,System.Threading.Monitor还提供多个函数使用
Enter尝试获取一个对象,同时第二个可选参数返回是否获取成功
TryEnter尝试获取一个对象,并在第二个可选参数上设置尝试的等待时间
Wait释放获得的对象,并在第二个可选参数时间后再次尝试获取该对象(即排队到自己后,自己办理中途整理资料停一会,让给其他人办,然后继续办理)
Exit释放获得的对象,和Wait类似,但不阻塞当前线程,也不尝试再次获取该对象
Pulse(),PulseAll()向一个或多个等待线程发送信号,表示自己即将释放对象,请大家做好准备,一般在Exit或者Wait前调用,可提高性能。
三、Mutex类
名字叫互斥锁(互斥体,互斥量),可用于多线程,功能类似Monitor,但它主要的用途不是用于多线程,而是用于进程。
特点仍然是拥有执行权的线程可以多次拥有,但也必须多次释放。
使用方法
private static System.Threading.Mutex mutex = null;//设置为static成员,是为了在整个程序生命周期内都持有Mutex /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { bool firstInstance; mutex = new System.Threading.Mutex(true, "name", out firstInstance); if (!firstInstance) { MessageBox.Show("存在"); return; } }
主要为2个函数ReleaseMutex和WaitOne,前者是释放,后者是等待释放的信号。
上面的代码的构造函数的第一个参数就是是否立即获取,第二个参数是互斥体的名称,注意是全局的,可以不填为匿名,但如果填了就不能再创建同名的互斥体(包括不同的软件,所以建议使用程序名)。
标签:
原文地址:http://www.cnblogs.com/21tcy/p/5019766.html