You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程安全自动清理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:58:11