更新类静态属性时使用的lock锁对象是否需要设置为static?
问题核心结论
你要保护的MyDictionary是类的静态属性,全局仅存一份,因此LockObject必须设置为静态。
为什么不能用实例锁对象
如果LockObject是实例成员,每个类实例都会持有独立的锁对象:当两个线程同时通过不同类实例触发字典初始化逻辑时,两个线程会分别拿到自己所属实例的锁对象,锁不互斥,最终会同时进入临界区,导致MyDictionary被重复初始化,甚至引发字典操作的并发异常。
静态锁不会阻塞类的其他实例
你的担心是多余的,原因有二:
- 这个锁仅作用于
MyDictionary的初始化逻辑,你类的其他业务逻辑只要没有使用这个静态锁对象,完全不会被该锁影响 - 你用的是双重检查锁模式,只要
MyDictionary初始化完成,最外层的非空判断会直接跳过锁逻辑,后续所有访问都不会触发锁操作,没有额外开销也不会产生阻塞
更简洁的线程安全懒加载方案(C#)
你可以直接用.NET内置的Lazy<T>类型实现静态字典的线程安全懒加载,不需要自己手写双重检查锁和锁对象:
// 定义静态懒加载属性 public static readonly Lazy<Dictionary<YourKey, YourValue>> MyDictionary = new(() => { var dict = new Dictionary<YourKey, YourValue>(); BuildDictionary(dict); return dict; }); // 使用时直接访问Value属性即可,天然保证仅初始化一次 var dictItem = MyDictionary.Value[someKey];
内容的提问来源于stack exchange,提问作者Jonathan Wood
相关产品推荐
相关产品推荐

