Я реализую простой кеш в C # и пытаюсь сделать его доступным из нескольких потоков. В базовом случае чтения это просто:
var cacheA = new Dictionary<int, MyObj>(); // Populated in constructor
public MyObj GetCachedObjA(int key)
{
return cacheA[key];
}
Это, я считаю, полностью потокобезопасно. Но я также хотел бы сделать это самозагрузочным. То есть, если кеш не заполняется при доступе, он заполняет его до выполнения запроса доступа.
Dictionary<int, MyObj> cacheB = null;
public MyObj GetCachedObjB(int key)
{
if (cacheB == null)
{
PopulateCacheB();
}
return cacheB[key];
}
private void PopulateCacheB()
{
cacheB = new Dictionary<int, MyObj>();
foreach (MyObj item in databaseAccessor)
{
cacheB.Add(item.Key, item);
}
}
Это не потокобезопасно, поскольку поток может получить доступ к GetCachedObjB после создания экземпляра cacheB, но до его полного заполнения, если другой поток находится в процессе его заполнения.
Итак, каков наилучший способ выполнить блокировку для cacheB, чтобы кэш был потокобезопасным?