Необходим ли замок в этой ситуации?
Нужно ли защищать доступ к одной переменной ссылочного типа в многопоточном приложении? В настоящее время я блокирую эту переменную следующим образом:
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
все зависит от того, будет ли доступ к ресурсу несколькими потоками. и некоторая переменная называется атомной операцией, в этом случае с атомной операцией нет необходимости использовать блокировку. извините за плохой английский.
в вашем случае, неизменный, я думаю, что блокировка не нужна.