

新闻资讯
技术学院应使用ConcurrentDictionary替代static Dictionary,因其采用分段锁与CAS保证线程安全;静态List则优先选用ConcurrentQueue或ConcurrentBag,避免手动加锁引发死锁或性能问题。
static Dictionary 会出问题因为 Dictionary 和 List 都不是线程安全的。高并发下多个线程同时调用 Add、Remove 或遍历,可能触发 InvalidOperationException(“集合已修改”),甚至出现数据丢失、索引越界或内存损坏——这不是偶发 bug,而是确定性崩溃。
ConcurrentDictionary 替代静态 Dictionary
这是最直接的替换方案,它内部用分段锁 + CAS 操作保证读写安全,且读操作无锁,性能远好于全局 lock。
GetOrAdd(key, factory) 是原子的,适合缓存场景,避免重复初始化AddOrUpdate(key, addValueFactory, updateValueFactory) 可安
全处理“有则更新、无则添加”逻辑foreach 是安全的,但迭代器看到的是快照,不反映实时增删Keys 或 Values 属性后直接遍历——它们返回的是只读集合,但底层仍可能被其他线程修改,建议先转成数组:var keys = dict.Keys.ToArray();
List 的安全替代:优先用 ConcurrentQueue 或 ConcurrentBag
如果只是追加+消费(如日志缓冲、任务队列),别硬扛 List + lock。静态 List 几乎没有安全又高效的并发使用方式。
ConcurrentQueue:FIFO,Enqueue/TryDequeue 全部线程安全,无锁实现,适合生产者-消费者模型ConcurrentBag:无序,对“同一线程频繁 Add/Remove”做了本地缓存优化,适合短期对象池场景ImmutableList + 原子更新:list = list.Add(item); // 返回新实例,旧引用不变但注意内存开销和 GC 压力
lock 时,必须避开常见陷阱静态锁对象必须是私有、只读、不可变的,且不能是 typeof(MyClass) 或字符串字面量——它们可能被外部代码锁定,引发死锁或锁竞争放大。
private static readonly object _lockObj = new object();
lock,只锁真正共享修改的几行ConcurrentDictionary 和 ConcurrentQueue 已覆盖绝大多数场景;手动加锁是最后手段,且一旦引入,就必须严格控制锁对象生命周期和临界区范围。