Как обновить Atomic на основе условия?

Как обновить AtomicInteger если его текущее значение меньше заданного значения? Идея такова:

AtomicInteger ai = new AtomicInteger(0);
...
ai.update(threadInt); // this call happens concurrently
...
// inside AtomicInteger atomic operation
synchronized {
    if (ai.currentvalue < threadInt)
        ai.currentvalue = threadInt;
}

Ответы

Ответ 1

Если вы используете Java 8, вы можете использовать один из новых методов обновления в AtomicInteger, который вы можете передать лямбда-выражению. Например:

AtomicInteger ai = new AtomicInteger(0);

int threadInt = ...

// Update ai atomically, but only if the current value is less than threadInt
ai.updateAndGet(value -> value < threadInt ? threadInt : value);

Ответ 2

Если у вас нет Java 8, вы можете использовать CAS-цикл следующим образом:

while (true) {
    int currentValue = ai.get();
    if (newValue > currentValue) {
        if (ai.compareAndSet(currentValue, newValue)) {
            break;
        }
    }
}

Ответ 3

Если бы у меня не было Java 8, я бы, вероятно, создал утилиту, например:

public static boolean setIfIncreases(AtomicInteger ai, int newValue) {
    int currentValue;
    do {
        currentValue = ai.get();
        if (currentValue >= newValue) {
            return false;
        } 
     } while (!ai.compareAndSet(currentValue, newValue));
     return true;
}

Из кода OP он затем будет вызываться следующим образом:

AtomicInteger ai = new AtomicInteger(0);

int threadInt = ...

// Update ai atomically, but only if the current value is less than threadInt
setIfIncreases(ai, threadInt);