Блокировка интернированной строки?

Обновление: Это приемлемо, если этот метод не является потокобезопасным, но мне интересно узнать, как я сделает его потокобезопасным. Кроме того, я не хочу блокировать один объект для всех значений ключа , если я могу этого избежать.

Исходный вопрос: Предположим, я хочу написать функцию более высокого порядка, которая принимает ключ и функцию и проверяет, был ли объект кэширован с данным ключом. Если есть, возвращается кешированное значение. В противном случае данная функция запускается, а результат кэшируется и возвращается.

Вот упрощенная версия моего кода:

public static T CheckCache(string key, Func fn, DateTime expires)
{
    object cache = HttpContext.Current.Cache.Get(key);
    //clearly not thread safe, two threads could both evaluate the below condition as true
    //what can I lock on since the value of "key" may not be known at compile time?
    if (cache == null)
    {
        T result = fn();
        HttpContext.Current.Cache.Insert(key, result, null, expires, Cache.NoSlidingExpiration);
        return result;
    }
    else
        return (T)cache;
}

Кроме того, предположим, что я не знаю всех возможных значений ключа во время компиляции .

Как я могу сделать этот поток безопасным? Я знаю, что здесь мне нужно ввести блокировку, чтобы 1+ потоки не оценили мое условие как истинное, но я не знаю, что заблокировать. Многие из прочитанных мной примеров блокировки (например, статья Джона Скита ) рекомендуют использовать «фиктивную» частную переменную, которая используется только для блокировки. В данном случае это невозможно, потому что во время компиляции ключи неизвестны. Я знаю, что могу тривиально сделать этот поток безопасным, используя одну и ту же блокировку для каждого ключа , но это может быть расточительным.

Теперь мой главный вопрос:

Можно ли заблокировать на клавише ? Поможет ли здесь интернирование строк?

После прочтения интернирования строк в .NET 2.0 наизнанку я понимаю, что могу явно вызвать String.Intern () для получения сопоставления 1 к 1 от значения строки до экземпляра строки. Подходит ли это для блокировки? Давайте изменим приведенный выше код на:

public static T CheckCache(string key, Func fn, DateTime expires)
{
    //check for the scenario where two strings with the same value are stored at different memory locations
    key = String.Intern(key); 
    lock (key) //is this object suitable for locking?
    {
        object cache = HttpContext.Current.Cache.Get(key);
        if (cache == null)
        {
            T result = fn();
            HttpContext.Current.Cache.Insert(key, result, null, expires, Cache.NoSlidingExpiration);
            return result;
        }
        else
            return (T)cache;
    }
}

Является ли приведенная выше реализация потокобезопасной?

17
задан wsanville 10 August 2011 в 12:06
поделиться