Как помогает бесконечный цикл?
Это означает: повторяйте попытку, пока не сработает. Без цикла это может не сработать с первого раза (см. ниже).
Какие могут быть сценарии, при которых условие «if (compareAndSet(current, next))» может вернуть false ?
Это происходит, если два потока пытаются изменить значение одновременно. Один из них доберется туда первым. Другой потерпит неудачу.
Представьте, что два потока (A и B) пытаются увеличить число с 5 до 6.
A: int current = get(); // current = 5
B: int current = get(); // current = 5
B: int next = current + delta; // next = 6
B: if (compareAndSet(current, next)) // OK
return next;
A: int next = current + delta; // next = 6
A: if (compareAndSet(current, next))
// fails, because "current" is still 5
// and that does not match the value which has been changed to 6 by B
Обратите внимание, что весь смысл этого класса в том, чтобы избежать блокировок. Вместо этого у вас есть этот «оптимистичный контроль валюты»: просто предположите, что никто другой не работает с данными в то же время, и если это окажется неправильным, откатитесь и повторите попытку.
В таком случае код может зайти в бесконечный цикл.
Не совсем. Он может дать сбой только один раз для каждого другого потока, который что-то делает со значением.
Поток A сверху во второй итерации:
A: int current = get(); => current now 6
A: int next = current + delta; => next = 7
A: if (compareAndSet(current, next)) => now OK
Вполне возможно, что один поток будет ждать вечно, если другие потоки будут постоянно обновлять значение, но только в этом случае. Чтобы избежать этого, вам понадобится некоторое определение «справедливости» (которое поддерживают некоторые другие инструменты в пакете параллелизма).
person
Thilo
schedule
17.07.2013