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的更多相关文章

  1. C# 对象锁

    现在有一种场景,服务端将一个任务派发给10个客户端执行,所有客户端执行完后,整个任务才算执行完. 每个客户端执行完后,通过http发送一个完成的消息给服务端,服务端发送邮件通知给用户. 当10个客户端 ...

  2. 命名空间System.Threading命名空间的同步锁 Monitor类

    官方备注: Monitor类通过向单个线程授予对象所来控制对对象的访问.对象所提供限制访问代码块的能力.当一个线程拥有对象的锁时,其他任何线程都不能获取该锁.还可以使用Monitor来确保不会允许其他 ...

  3. Thread锁 Monitor类、Lock关键字和Mutex类

    Monitor 类锁定一个对象 当多线程公用一个对象时,也会出现和公用代码类似的问题,这种问题就不应该使用lock关键字了,这里需要用到System.Threading中的一个类Monitor,我们可 ...

  4. 一张图讲解对象锁和关键字synchronized修饰方法

    每个对象在出生的时候就有一把钥匙(监视器),那么被synchronized 修饰的方法相当于给方法加了一个锁,这个方法就可以进行同步,在多线程的时候,不会出现线程安全问题. 下面通过一张图片进行讲解: ...

  5. synchronized同步对象锁

    package com.system.util; import com.common.Constants; import com.util.Cache; /** * 创建同步对象锁 * * @auth ...

  6. java synchronized类锁,对象锁详解(转载)

    觉得还不错 留个记录,转载自http://zhh9106.iteye.com/blog/2151791 在java编程中,经常需要用到同步,而用得最多的也许是synchronized关键字了,下面看看 ...

  7. java 哪些情况下会使对象锁释放

    Java_多线程_锁释放 问:Java多线程运行环境中,在哪些情况下会使对象锁释放?答:由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的 ...

  8. 多线程并发 synchronized对象锁的控制与优化

    本文针对用户取款时多线程并发情境,进行相关多线程控制与优化的描述. 首先建立用户类UserTest.业务操作类SynchronizedTest.数据存取类DataStore,多线程测试类MultiTh ...

  9. Java:使用synchronized和Lock对象获取对象锁

    在并发环境下,解决共享资源冲突问题时,可以考虑使用锁机制. 1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数变为0.在任务(线程)第一次给对象加锁 ...

随机推荐

  1. centos中docker mongodb 配置

    安装docker,对于Centos7,如下: $ sudo yum update$ sudo yum -y install docker$ sudo systemctl start docker 首先 ...

  2. winfrom组件圆角

    精简后,就其实一点,只要有paint事件的组件,都可画圆角,没有的外面套一个panel就行了. using System; using System.Collections.Generic; usin ...

  3. 15分钟学会Lua

    lua的很多语法跟matlab很像 最基本的赋值是一样的 循环和选择判断后面必须跟一个关键字:do和then ,, do ... end if - then - end table是lua的唯一一种数 ...

  4. 通读SDWebImage③--gif和webP的支持、不同格式图片的处理、方向处理

    本文目录 NSData+ImageContentType: 根据NSData获取MIME UIImage+GIF UIImage+WebP UIImage+MultiFormat:根据NSData相应 ...

  5. RequireJS与SeaJS模块化加载示例

    web应用越变的庞大,模块化越显得重要,尤其Nodejs的流行,Javascript不限用于浏览器,还用于后台或其他场景时,没有Class,没有 Package的Javascript语言变得难以管理, ...

  6. *HDU 1237 栈

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  7. 猥琐的wordpress后门分享

    https://www.t00ls.net/thread-37312-1-1.html 一个可以自动调用管理员帐号登录wordpress后台的方法. <?php require('../../. ...

  8. MySql怎样去掉某个字段最后的逗号或最后的字

    update 表 set 字段=left(字段,char_length(字段)-1) where right(字段,1)=',';

  9. SQL语句操作数据与一些函数使用的丰富数据库

    数据库有多重要,其实不用我说,但该怎么运用好数据库下SQL语句与其它的如“函数”等等,那就需要我们大家多多去练习并总结其中的窍门,或许你的总结没那么好,担只要你的练习足够多,就算那不是窍门,那也将是你 ...

  10. 串口实现FIFO接受数据

    基本原理:静态队列 /* * 串口的FIFO简单读取实现 * 功能,实现串口的FIFO实现 * 使用方法: * 版本:v1.0.0 * */ #include "sys.h" #i ...