C#面试题更新 2026-08-03

请解释 C# 中 lock 关键字实现线程同步的底层机制是怎样的?

考察说明

考查对 C# 中 lock 关键字实现线程同步底层原理的理解。

回答思路

  1. 【回答框架 1】lock 是 C# 提供的语法糖,其底层通过 Monitor 类实现。编译器将 lock 语句转换为 try-finally 块,并在 try 块入口调用 Monitor.Enter,在 finally 块中调用 Monitor.Exit,确保锁被正确释放,即使发生异常也能释放锁。
  2. 【回答框架 2】Monitor.Enter 会尝试获取对象上的互斥锁。若锁未被占用,则当前线程获得锁;若已被占用,则当前线程阻塞,直到锁被释放。Monitor 还支持可重入,即同一线程可以多次获取同一把锁,每次进入时计数器加一,每退出一次计数器减一,只有计数器归零时才真正释放锁给其他线程。
  3. 【回答框架 3】锁的底层依赖于操作系统原语,如 Windows 上的关键段或更高效的混合锁机制。Monitor 在获取锁时先进行用户态的自旋等待,若自旋超时则切换到内核态阻塞线程,以减少上下文切换开销。C# 中 lock 的对象可以是任意引用类型,但通常使用专门的锁对象,避免对公共对象或 this 加锁。
  4. 【回答框架 4】lock 只保证互斥访问,不保证业务幂等性。要保证幂等,还需唯一标识、状态记录、唯一约束或去重等额外机制。线程池场景下,lock 不会阻塞线程池线程,而是阻塞调用线程。
  5. 【关键点 1】lock 通过 Monitor.Enter 和 Monitor.Exit 实现互斥。
  6. 【关键点 2】Monitor 支持可重入和计数器机制。
  7. 【关键点 3】底层涉及用户态自旋和内核态阻塞。
  8. 【关键点 4】应避免对公共对象或 this 加锁。
  9. 【关键点 5】lock 只保证互斥,不保证幂等。
  10. 【易错点 1】不能直接说 lock 保证业务幂等,需额外机制。
  11. 【易错点 2】避免对字符串、公共对象或 this 加锁。
  12. 【易错点 3】不要混淆 lock 与信号量或读写锁的语义。