请阐述 C# 中 lock 语句的功能,并说明如何利用它来处理多线程环境下的同步问题?
考察说明
考察对 C# lock 语句的理解及在多线程同步中的应用能力。
回答思路
- 【回答框架 1】lock 语句是 C# 中用于实现线程同步的关键字,确保同一时刻只有一个线程能进入临界区,从而保护共享资源。
- 【回答框架 2】典型使用方式为 lock(obj) { ... },推荐使用私有只读对象作为锁,避免锁公共对象或字符串,防止死锁或性能下降。
- 【回答框架 3】当线程进入 lock 块时,会尝试获取互斥锁,若已被持有则阻塞等待,直到持有线程退出并释放锁。
- 【回答框架 4】lock 实现依赖于 Monitor 类,等价于 Monitor.Enter 和 Monitor.Exit,支持可重入性,同一线程可多次进入。
- 【回答框架 5】使用 lock 可避免竞态条件,但需注意锁粒度,过大会降低并发性能,且不能解决所有并发问题。
- 【关键点 1】lock 保证互斥访问,适用于保护共享资源的读写。
- 【关键点 2】推荐使用私有对象作为锁对象,避免锁定 this 或 typeof。
- 【关键点 3】lock 可重入,同一线程可多次获取,不会自我死锁。
- 【关键点 4】锁的持有时间应尽可能短,以减少性能开销。
- 【易错点 1】锁定公共对象或字符串常量可能导致意外死锁。
- 【易错点 2】过大锁粒度或错误嵌套可能导致性能瓶颈或死锁。
- 【易错点 3】lock 仅保证原子性,不保证其他并发问题如可见性,可结合 volatile 或使用更高层次同步构造。