У меня есть частная коллекция (например, ISet<int>
), доступ к которой можно изменить или изменить несколькими потоками.
У меня есть logi c, так что этой теме нужно только изменить ISet
в определенные состояния, тогда как другой поток всегда должен мутировать его. Другой поток всегда будет принимать lock
, реализовав ключевое слово lock
для ISet
следующим образом:
lock (this._set)
{
// some mutating operation on this._set
}
Для этого потока мне нужно только выполнить операцию, которая изменяет поток, если ISet
содержит int
, называемый currentValue
, что в этом случае встречается редко. Операция в другом потоке является частой. Поэтому вопрос заключается в том, могу ли я проверить, содержит ли ISet
currentValue
перед тем, как взять lock
, чтобы минимизировать время, в течение которого этот поток блокирует другой поток, например:
if (this._set.Contains(currentValue))
{
lock (this._set)
{
if (this._set.Contains(currentValue))
{
// some mutating operation on this._set
}
}
}
Вопрос в том, является ли поведение проверки вне lock
неопределенным или может ли это привести к переводу ISet
в неопределенное или неожиданное состояние. Конечно, фактическое возвращаемое значение нельзя доверять, поэтому его снова проверяют внутри lock
, но действительно ли это допустимая оптимизация, которую я могу ожидать, или она испортит некоторое внутреннее состояние набора? Цель состоит в том, чтобы использовать lock
в этой теме как можно реже.