C# 对象锁——Monitor
Monitor里边有一些static方法,可以用于在对象上获取同步锁,来进行一些进程同步控制操作

用法及注意点如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace myTest
{
class Program
{
// 一个比较容易犯的错误
// 使用 Monitor 锁定对象(即引用类型)而不是值类型。将值类型变量传递给 Enter 时,
//它被装箱为对象。如果再次将相同的变量传递给 Enter,则它被装箱为一个单独对象,而且线程不会阻止。Monitor
//本应保护的代码未受保护。此外,将变量传递给 Exit 时,
//也创建了另一个单独对象。因为传递给 Exit 的对象和传递给 Enter 的对象不同,Monitor
//将引发 SynchronizationLockException
//这种情况最好用 Interlocked 来完成
private static int _num = ;
// 装箱一下就可以了
private static object num = _num;
static void Main(string[] args)
{ Thread t1 = new Thread(new ThreadStart(addNum));
t1.Name = "线程1";
Thread t2 = new Thread(new ThreadStart(addNum));
t2.Name = "线程2";
t1.Start();
t2.Start();
Console.ReadLine();
}
//|- 拥有锁的线程 lockObj->|- 就绪队列(ready queue) |- 等待队列(wait queue)
// 就绪队列:尝试lock对象的线程
// 等待队列:在等待中, !!!不会主动!!! 去lock对象的线程 Monitor.wait 会使线程进入等待队列
// 如果只调用wait不调用pulse,可能使线程进入死锁
// 下面执行的时间线: t1获得锁——t1打印——2000ms——t1Pulse(此时无线程在等待队列,故无效)——2000ms——t1释放锁并进入等待队列——
// t2获得锁——t2打印——2000ms——t2Pulse(此时t1线程在等待队列,t1进入就绪队列)——2000ms——t2释放锁并进入等待队列——
// t1获得锁——t1Pulse(此时t2线程在等待队列,t2进入就绪队列)——t1打印——t1释放锁——t1退出——
// t2获得锁——t2Pulse(此时无线程在等待队列,故无效)——t2打印——t2释放锁——t2退出
private static void addNum()
{
Boolean gotLock = false;
try
{
// Monitor.Enter(num); //获取排它锁
Monitor.Enter(num, ref gotLock);
Console.WriteLine(Thread.CurrentThread.Name+ DateTime.Now.ToString() + "——————" + num);
//释放锁并让线程进入等待队列,直到它重新获得锁
Thread.Sleep();
//通知等待的线程进入就绪队列,有锁了
Monitor.Pulse(num);
Thread.Sleep();
Monitor.Wait(num);
Monitor.Pulse(num);
}
finally
{
Console.WriteLine(Thread.CurrentThread.Name + DateTime.Now.ToString() + "——————" + num);
if (gotLock)
{
Monitor.Exit(num);
}
}
}
}
}
运行结果:

用Monitor类获得对象锁的try .. catch finally的过程还有一个语法糖,lock关键字
C# 对象锁——Monitor的更多相关文章
- C# 对象锁
现在有一种场景,服务端将一个任务派发给10个客户端执行,所有客户端执行完后,整个任务才算执行完. 每个客户端执行完后,通过http发送一个完成的消息给服务端,服务端发送邮件通知给用户. 当10个客户端 ...
- 命名空间System.Threading命名空间的同步锁 Monitor类
官方备注: Monitor类通过向单个线程授予对象所来控制对对象的访问.对象所提供限制访问代码块的能力.当一个线程拥有对象的锁时,其他任何线程都不能获取该锁.还可以使用Monitor来确保不会允许其他 ...
- Thread锁 Monitor类、Lock关键字和Mutex类
Monitor 类锁定一个对象 当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可 ...
- 一张图讲解对象锁和关键字synchronized修饰方法
每个对象在出生的时候就有一把钥匙(监视器),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题. 下面通过一张图片进行讲解: ...
- synchronized同步对象锁
package com.system.util; import com.common.Constants; import com.util.Cache; /** * 创建同步对象锁 * * @auth ...
- java synchronized类锁,对象锁详解(转载)
觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...
- java 哪些情况下会使对象锁释放
Java_多线程_锁释放 问:Java多线程运行环境中,在哪些情况下会使对象锁释放?答:由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的 ...
- 多线程并发 synchronized对象锁的控制与优化
本文针对用户取款时多线程并发情境,进行相关多线程控制与优化的描述. 首先建立用户类UserTest.业务操作类SynchronizedTest.数据存取类DataStore,多线程测试类MultiTh ...
- Java:使用synchronized和Lock对象获取对象锁
在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制. 1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数变为0.在任务(线程)第一次给对象加锁 ...
随机推荐
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- Torch Problems: require some packages doesn't work
I've recently got a problem. require 'cutorch' doesn't work. But it was ok yesterday, although I hav ...
- tcpdump
tcpdump tcp -i eth1 -t -s -c and dst port ! and src net -w ./target.cap (1)tcp: ip icmp arp rarp 和 t ...
- 干掉命令行窗口下MySql乱码
晚上重温dos窗口操作mysql的时候,遇到了一个巨蛋疼的问题------>中文验证码 -->_-->,所以找了找资料弄懂了怎么解决乱码问题,,小记一下. 新建一个表 create ...
- C\C++ 生成各位数不相等的随机数
最近想写一个1A2B的小游戏来练习一下,结果在第一步生成随机数的时候就遇到了一点点问题. 游戏初始化时需要先生成一个四位随机数,且各位各不相等.于是最开始的思路是生成一个整数数组,只需要判断生成的随机 ...
- canvas生成图片并保存到本地文件夹主要代码
js var url = canvas.toDataURL();//把canvas中的图片变成data:image C# string filepath = ""; string ...
- JDBC的连接和增删改和查找
package Test2;import java.sql.*;import java.sql.DriverManager;import java.sql.SQLException;public cl ...
- 【图文教程】Eclipse for PHP+XAMPP调试配置
一.下载安装XAMPP 下载地址:https://www.apachefriends.org/download.html, 一路“Next”,安装完毕. 二.下载Eclipse for PHP 下载地 ...
- 10年微软MVP路(如何成为一个MVP?)
搞微软技术的,大家或多或少都有听说过微软的"最有价值专家"(MVP), 从2006年到2015年连续10年ASP.NET/IIS MVP.当年很多一起搞微软技术的朋友都转搞其他非微 ...
- PostgreSQL 9.3发布
9月9日,PostgreSQL全球开发组宣布了9.3版发布的消息.从2010年9.0版开始,PostgreSQL已经连续四个版本稳定地按时在每年9月中旬发布,从一个侧面也显示了开发团队的强大实力. 9 ...