Рассмотрим следующий код, который выполняется в фоновом потоке («поток B»):
List<T> invocationQueueCopy;
lock (invocationQueue)
{
invocationQueueCopy = invocationQueue;
invocationQueue = new List<T>();
}
В другом потоке («поток A») я просто блокирую «invocationQueue» перед добавлением в него:
lock (invocationQueue)
{
invocationQueue.Add(args);
}
Я читал, что присвоение ссылок является атомарным, но может когда-нибудь случиться так, что «поток А» в конечном итоге выполнит запись в старый список (тот, который был заменен в «потоке В») после получениязамок?Я читал другие ответы, которые подразумевают, что это могло бы быть, если бы значение ссылки хранилось в регистре в «потоке A», тогда он не знал бы, что «поток B» изменил значение в классе.Если это так, может ли объявление «invocationQueue» volatile предотвратить это?
Примечания:
- Я знаю, что могу клонировать, а затем очистить список.
- Я знаю, что яможет иметь отдельный объект блокировки для списка.
Но я бы предпочел не делать ни одну из этих вещей, если это не требуется.
Заранее спасибо.
Редактировать:
Просто чтобы уточнить из комментариев Адама: invocationQueue - это закрытое поле, которое создается внутри этого класса и никогда не подвергается воздействию внешнего мира, поэтому ничто не может заблокировать его, кроме этих двухметоды.