2

我已经使用字典类实现了一个简单的缓存:

private Dictionary<int, byte[]> cache = new Dictionary<int, byte>();

public void SetPicture(int id, byte[] bytes)
{
    cache[id] = bytes;
}

public byte[] GetPicture(int id)
{
    if (cache.Contains(id)) {
        return cache[id];
    }
    return null;
}

SetPicture 仅从单个后台线程调用。(此后台线程正在从活动目录查询中更新用户个人资料图片)。

GetPicture 从多个其他线程(处理 http 请求的线程)调用。

项目永远不会从缓存中删除。

那么这个代码线程安全吗?或者我是否需要在 SetPicture 中写入时阻止对内部字典的访问?

4

2 回答 2

6

不,这不安全;所有对字典的访问都需要同步,因为 a 的内容Dictionary<,>不能保证读者与作者的对抗。此外,单独的包含/获取检查是明显的线程竞争。

选项:

  • 使用 1.1 样式Hashtable- 支持一个写入器多个并发读取器而不 同步(这里的缺点是您的键 ,int是一个值类型,因此需要装箱;Hashtable使用引用类型键时更有吸引力,例如作为string
  • 用一个ConcurrentDictionary<,>
  • 用于ReaderWriterLockSlim同步(假设读取比写入更常见)
  • 用于lock同步(假设非平凡的写入)

然而!如果您使用该Hashtable方法,请不要单独执行Contains/ 获取 - 只需使用索引器。如果你得到null它不在那里。否则你有一个竞争条件。

于 2012-06-06T07:13:23.680 回答
2

不是线程安全的。使用并发字典。如果找不到条目,​​GetPicture 也必须返回一些东西。

于 2012-06-06T07:14:59.463 回答