lock是C#基于Monitor.Enter/Exit的语法糖,需用private readonly object字段作锁对象,避免用this、字符串等;不支持异步,高并发下应优先考虑Interlocked、Concurrent集合或AsyncLock。

lock 是 C# 中最常用、最简洁的线程同步机制,本质是基于 Monitor.Enter 和 Monitor.Exit 的语法糖,用于确保同一时刻只有一个线程能进入被保护的代码块。
lock 的基本用法和正确写法
必须用一个**引用类型对象**(通常为 private readonly object 字段)作为锁对象,不能用值类型或字符串字面量,否则会因装箱/字符串驻留导致意外共享锁。
✅ 推荐写法:声明私有只读对象字段作为锁
private readonly object _lockObj = new object();public void DoWork(){lock (_lockObj){// 这里是临界区,同一时间仅一个线程可执行SharedCounter++;}}
❌ 错误示例:用 this、typeof(…)、字符串或 public 字段作锁 —— 容易引发死锁或锁粒度失控⚠️ 注意:lock 块内避免调用外部方法(尤其可能再次加锁或阻塞的操作),防止死锁或延长锁持有时间
lock 和 Monitor 的关系
lock 编译后等价于 try-finally 中调用 Monitor.Enter/Exit,确保即使发生异常也能释放锁:
lock (obj) { ... }// 等价于:Monitor.Enter(obj);try{ ...}finally{ Monitor.Exit(obj);}
Monitor 还支持超时(Monitor.TryEnter(obj, timeout))、条件等待(Monitor.Wait/Pulse)等高级操作,lock 不直接支持这些若需等待唤醒逻辑(如生产者-消费者),应直接使用 Monitor 或更现代的 SemaphoreSlim、AsyncLock(.NET 6+)
常见误区与替代方案
lock 虽简单,但不是万能解。高并发场景下过度使用会严重降低吞吐量。
❌ 不要 lock(this):外部代码也可能锁定同一个实例,造成不可控竞争❌ 不要 lock(typeof(MyClass)):整个类型全局唯一,容易跨实例干扰✅ 更轻量替代:对简单计数器可用 Interlocked.Increment(ref counter)✅ 异步场景:lock 不支持 async/await,此时改用 AsyncLock(如 Microsoft.Threading.Tasks.Extensions)或 SemaphoreSlim.WaitAsync()
性能提示与调试建议
锁本身开销很小,但争用(多个线程频繁抢同一把锁)会导致线程挂起/唤醒,大幅拖慢性能。
用 Visual Studio 的“并发可视化工具”或 dotTrace 可观察锁争用热点优先缩小临界区:只锁真正共享数据访问的部分,而非整个方法考虑无锁编程(如 ConcurrentDictionary、ConcurrentQueue)或分段锁(如 .NET 的 ConcurrentDictionary 内部实现)
基本上就这些。lock 用对了很安全,用错了容易埋坑。关键是选对锁对象、控制好范围、别在锁里干重活。
以上就是C#怎么使用lock关键字 C#线程同步锁的使用方法的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1442819.html
微信扫一扫
支付宝扫一扫