Необходим ли замок в этой ситуации?

Нужно ли защищать доступ к одной переменной ссылочного типа в многопоточном приложении? В настоящее время я блокирую эту переменную следующим образом:

private readonly object _lock = new object();
private MyType _value;
public MyType Value
{
  get { lock (_lock) return _value; }
  set { lock (_lock) _value = value; }
}

Но мне интересно, действительно ли это необходимо? Не является ли присвоение значения атомному полю? Может ли что-то пойти не так, если я не заблокирую в этом случае?

P.S.: MyType - неизменяемый класс: все поля задаются в конструкторе и не изменяются. Чтобы что-то изменить, создается новый экземпляр и назначается переменной выше.

Ответ 1

Быть атомным редко бывает достаточно.

Я вообще хочу получить последнее значение для переменной, а не потенциально видеть устаревшую, поэтому требуется какой-то барьер памяти, как для чтения, так и для записи. Блокировка - это простой способ добиться этого, ценой потенциальной потери производительности из-за конкуренции.

Раньше я полагал, что сделать переменную volatile будет достаточно в этой ситуации. Я больше не уверен, что это так. В основном я теперь стараюсь избегать написания кода без блокировки, когда задействованы общие данные, если только я не могу использовать строительные блоки, написанные людьми, которые действительно понимают эти вещи (например, Джо Даффи).

Ответ 2

Для этого есть volatile. Безопасно ли это, не зависит от сценария. Но компилятор может сделать смешные вещи, например, реорганизовать порядок работы. Поэтому даже чтение/запись в одно поле может быть небезопасным.

Ответ 3

Это может быть проблема. Это не просто задание, о котором вы должны беспокоиться. Из-за кэширования параллельные потоки могут видеть старую версию объекта, если вы не заблокируете. Таким образом, зависит ли блокировка от того, как вы ее используете, и не показываете это.

Здесь свободная, образец главы "Параллельное программирование в Windows" , которая подробно объясняет эту проблему.

Ответ 4

все зависит от того, будет ли доступ к ресурсу несколькими потоками. и некоторая переменная называется атомной операцией, в этом случае с атомной операцией нет необходимости использовать блокировку. извините за плохой английский.

в вашем случае, неизменный, я думаю, что блокировка не нужна.