2013-11-26 2 views
0

В проекте служб Windows (C# .Net Platform) мне нужно предложение.
В проекте у меня есть класс с именем Cache, в котором я сохраняю некоторые данные, которые мне нужны часто. Существует поток, который обновляет кеш через каждые 30 минут. Где есть несколько потоков, которые используют данные кеша.
В классе кеша есть функции getter и setter, которые используются потоками пользователей и потоком обновления кэша соответственно. Никто не использует объекты данных, например таблицы, потому что они являются частными членами.
Из приведенного выше контекста, как вы думаете, я должен использовать функции блокировки в классе кеша?Должен ли я блокировать данные в многопоточной парадигме?

+0

- это кеш-синглтон? существуют ли потоки с более высоким приоритетом, чем поток обновления? – Pandrei

+0

Да, кеш одинарный. –

+0

Sidenote - есть библиотеки для кеширования, которые делают то же самое - например, Microsoft Enterprise Library. Зачем изобретать колесо? –

ответ

1

Эффекты от использования блокировок при записи в общую папку (например, кеш) действительно зависят от приложения. Если код использовался в банковском программном обеспечении, результаты могут быть катастрофическими.

Как правило, большой палец - когда несколько потоков обращаются к одному и тому же местоположению, даже если только одна запись протектора и все остальные считываются, вы должны использовать блокировки (для операции записи). Что может случиться, так это то, что один поток начнет считывать данные, вытащить поток обновления; Таким образом, это потенциально может привести к сочетанию старых и новых данных. Если это действительно влияет на приложение и насколько оно разумно.

1

Ключевой момент: Если вы не заблокируете чтение, есть шанс, что ваш текст не увидит изменений. Блокировка заставит ваш код чтения получать значения из основной памяти, а не извлекать данные из кеша или регистра. Чтобы избежать блокировки, вы можете использовать Thread.MemoryBarrier(), который будет выполнять ту же работу без накладных расходов, фактически блокируя что-либо.

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

Также: когда ваш геттер вызывается, помните, что он работает на многих других потоках. Существует тенденция думать, что когда-то что-то запускает код класса Cache, все это в одном потоке, и это не.

+0

Что вы предлагаете, следует ли мне блокировать кешированный объект при его обновлении в setter или прочитать его в getter? Я думаю, что блокировка в сеттере будет лучше! –

+0

@NadeemJamali: Оба! Мой ответ был сосредоточен на проблеме чтения; Я просто предполагал, что замок записи необходим. Вероятно, есть способы избежать блокировки здесь, но вам нужно делать другие вещи (например, неизменные объекты и изменчивые поля), и вы должны знать, что делаете. Ключевым моментом, который я пытался сделать, является то, что без блокировки ваших чтений, особенно если они происходят в течение нескольких секунд после записи, они вообще не видят изменений. Возможно, они будут видеть изменения только от нескольких обновлений или вообще никаких обновлений. – RalphChapin

Смежные вопросы