电话
400 9058 355
lock无限等待,Monitor.TryEnter可设超时;前者自动释放锁,后者需手动配对Exit并用lockTaken防护;Monitor支持Wait/Pulse实现条件等待,lock不支持。
这是最直接的区别:当你用 lock(obj),线程一旦抢不到锁,就会**无限阻塞**,直到前一个持有者释放;而 Monitor.TryEnter(obj, timeout) 允许你指定最多等多久(毫秒),超时就返回 false,不卡死。
timeout = 0 表示“只试一次”,立即返回成功或失败,常用于非阻塞轮询timeout = -1 等价于无限等待 —— 此时行为接近 lock,但依然要手动配对 Exit,没 lock 安全
lock 是语法糖,编译后自动包成 try-finally,哪怕临界区抛异常,锁也一定释放;Monitor.TryEnter 不带这种保障 —— 如果你忘了在 finally 里调用 Monitor.Exit,或者只在 if 分支里调了,就可能造成死锁。
bool lockTaken = false; try { if (Monitor.TryEnter(obj, 1000)) lockTaken = true; /* 临界区 */ } finally { if (lockTaken) Monitor.Exit(obj); }
lockTaken 判断?Monitor.Exit 会抛 SynchronizationLockException
Monitor.Exit 写在 if 里而不是 finally?异常一出,锁就永远拿不回来了如果你需要做生产者-消费者、信号量式唤醒、条件等待(比如“等队列不为空再取”),就必须用 Monitor.Wait 和 Monitor.Pulse —— 这些方法只能在已持有 Monitor 锁的前提下调用,而 lock 语法不暴露锁状态,也没法中途释放再等待。
Monitor.Wait(obj) 会**自动释放锁 + 挂起当前线程**,等别人 Pulse 后重新争锁lock 无法表达Monitor.Enter/TryEnter + Wait/Pulse 全套流程两者都要求锁对象是私有、引用类型、不可变(推荐 private readonly object _sync = new object(););但 Monitor 因为方法多、路径长,更容易踩坑:
Enter 但 Exit 次数不够?锁不会真正释放Monitor.Wait 或 Monitor.Pulse?直接抛 SynchronizationLockException
this 当锁对象?跨实例/跨程序集意外共享,引发隐蔽竞争Monitor.IsEntered(obj) 是调试用的,**不能用来代替 TryEnter 做锁检查**(它不保证原子性)简单场景无脑用 lock;只要出现“等太久不行”“我要等某个条件”“我得通知别人”,就得切到 Monitor,并且每一步都要对齐 Enter/Exit、Wait/Pulse 的契约 —— 少一个 finally,就少一分确定性。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...