如何根据条件更新一个原子?

11

如何在当前值小于给定值时更新 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;
}

请将工作代码粘贴在此处,即没有任何编译错误的代码。 - SMA
你发布的代码片段毫无意义。你首先使用 .update() 更新了 ai(不管你用它做什么),然后再检查新值。 - SubOptimal
3
这是个好问题,并且非常合理。至于批评:对于这个问题,原帖作者不可能编写可运行的代码。如果他这样做了,就需要知道答案,所以他只能发表伪代码。 - Daniel S.
3个回答

23

如果您正在使用Java 8,您可以使用AtomicInteger中的新更新方法之一,您可以通过它传递一个lambda表达式。例如:

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);

5

如果我没有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);

3

如果您没有Java 8,可以使用以下类似于CAS循环的方式:

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

我点击了-1,因为如果newValue <= currentValue,这段代码会导致无限循环。 - Mikko Östlund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接