Добрый день,
чем больше читаю про lock-free структуры данных и алгоритмы, тем больше путаницы и не уверенности порождаю в своем сознании. Дошло до того, что поймал себя на мысли, что не могу однозначно ответить на ряд простых с виду вопросов. Буду очень признателен, если кто то поможет упорядочить ту кашу, которая у меня сейчас вертится в голове. Ниже представлены типичные паттерны использования операции CAS:
1.
public static T
Change<T>(this T source, Func<T, T> operation)
where T : class
{
T original, value;
do
{
original = source;
value = operation(original);
}
while (Interlocked.CompareExchange(ref source, value, original) != original);
return original;
}
2.
public static T
Change<T>(this T source, Func<T, T> operation)
where T : class
{
var original = source;
while (true)
{
var value = operation(original);
if (Interlocked.CompareExchange(ref source, value, original) == original)
break;
}
return original;
}
3.
private double foo;
public double
Foo {
get { return this.foo; }
set
{
while (true)
if (Interlocked.CompareExchange(ref this.foo, this.foo + value, this.foo) == this.foo)
break;
}
}
Вопросы:
1. Имеет ли какое то значение порядок операций выделенных жирным в первом и втором примерах?
2. Тот же самый вопрос, но в случае использования подобного кода для value type?
3. Есть ли концептуальная разница между 1, 2 и 3 вариантами (за исключением первых двух вопросов) — меня смущает, что в ряде примеров авторы сохраняют исходное значение в отдельную переменную и так же поступают с вычисляемым значением, а в других нет.
4. Правильно, ли я понимаю, что CAS применяется, только при необходимости модификации shared данных
с учетом возможных изменений произведенных другими потоками? Иными словами, в случае, если перезатирание данных последним потоком является нормальным поведением программы, использования CAS излишне?
UPD:
5. При использовании CAS для List<T> с целью сохранения производительности, стоит ли в обязательном порядке переопределять методы Equals для типа с которым работает список? На сколько это вообще разумно применять CAS для generic коллекций?
Заранее благодарю за ответы!