线程安全自动清理Dictionary的实现及线程安全性验证
这个EventBusManager实现是否具备线程安全性?
结论:该实现是线程安全的,原因如下:
共享状态的访问全程受锁保护
核心共享资源buses字典(存储roomId与EventBus实例的映射)的所有读写操作(TryGetValue、Add、Remove),都被包裹在lock (buses)代码块中。由于Dictionary<TKey,TValue>本身不支持并发读写,锁机制避免了多线程同时操作字典导致的数据损坏或异常。UsageCount的修改无竞态条件
BusUsage.UsageCount的增减操作均在锁范围内执行,确保同一时间只有一个线程能修改计数,不会出现多个线程同时增减导致的计数错误。EventBus实例创建的原子性
当某个roomId首次被访问时,创建BusUsage实例并添加到字典的操作是在锁内完成的,避免了多线程同时为同一个roomId创建多个EventBus实例的情况,保证了"每个roomId对应唯一EventBus实例"的需求。
另外,锁对象选用了readonly的buses字典,确保锁对象不会被中途替换,避免了锁失效的风险。
// 原实现代码 public class EventBusManager { readonly Dictionary<string, BusUsage> buses = []; public EventBus GetIncrementUsage(string roomId) { lock (buses) { if (!buses.TryGetValue(roomId, out var busUsage)) { busUsage = new BusUsage(new EventBus()); buses.Add(roomId, busUsage); return busUsage.Bus; } busUsage.UsageCount++; return busUsage.Bus; } } public void DecrementUsage(string roomId) { lock (buses) { if (!buses.TryGetValue(roomId, out var busUsage)) return; busUsage.UsageCount--; if (busUsage.UsageCount == 0) buses.Remove(roomId); } } record BusUsage(EventBus Bus) { public int UsageCount = 1; }; }
内容的提问来源于stack exchange,提问作者user1167761
相关产品推荐
相关产品推荐

