Использование AtomicInteger безопасно проверить сначала - PullRequest
4 голосов
/ 30 марта 2012

Как я могу выполнить команду "проверить-затем-действовать" в переменной AtomicInteger?
Т.е. какой самый безопасный / лучший способ проверить значение такой переменной сначала и вкл/ dec в зависимости от результата?
Например (на высоком уровне)
if(count < VALUE) count++; // атомно, используя AtomicInteger

Ответы [ 2 ]

10 голосов
/ 30 марта 2012

Вам нужно написать цикл. Предполагая, что count является вашей AtomicInteger ссылкой, вы должны написать что-то вроде:

while(true)
{
    final int oldCount = count.get();
    if(oldCount >= VALUE)
        break;
    if(count.compareAndSet(oldCount, oldCount + 1))
        break;
}

Вышеуказанное будет повторяться до тех пор, пока: (1) ваше условие if(count < VALUE) не будет выполнено; или (2) count успешно увеличено. Использование compareAndSet для выполнения приращения позволяет нам гарантировать, что значение count по-прежнему равно oldCount (и, следовательно, по-прежнему меньше VALUE), когда мы устанавливаем его новое значение.

1 голос
/ 04 февраля 2017

Вы можете решить эту проблему следующим образом, если используете Java 8. Это потокобезопасно и выполняется атомарно.

AtomicInteger counter = new AtomicInteger();
static final int COUNT = 10;

public int incrementUntilLimitReached() {
    return counter.getAndUpdate((n -> (n < COUNT) ? n + 1 : n));
}
...