java - 大于比较和交换

标签 java multithreading synchronization nonblocking

正如标题所暗示的,我正在寻找一个比较和交换实现,但具有大于比较:

if(newValue > oldValue) {
    oldValue = newValue;
}

其中 oldValue 是一些全局共享状态,newValue 是每个线程私有(private)的,无需这样做:

synchronized(locker) {
    if(newValue > oldValue) {
        oldValue = newValue;
    }       
}

因为我想要一个非阻塞的解决方案。通过研究其他非阻塞操作的源代码,我想出了这个(假设值是整数):

AtomicInteger oldValue; // shared global variable

...

public boolean GreaterThanCAS(int newValue) {

    while(true) {
        int local = oldValue;
        if(local == oldValue) {
            if(newValue > local) {
                 if(oldValue.compareAndSet(local, newValue) {
                     return true;  // swap successful
                 } // else keep looping
            } else {
                 return false; // swap failed
            }
        } // else keep looping
    }
}

//else keep looping 发生时,这意味着另一个线程同时更改了 oldValue ,所以我需要循环并重试。

这个实现是否正确(线程安全)?

最佳答案

从 Java 8 开始,这可以通过使用 updateAndGet 来简化。 :

public boolean greaterThanCAS(int newValue) {
    return oldValue.updateAndGet(x -> x < newValue ? newValue : x) == newValue;
}

请注意,如果旧值和新值相等,这也会返回 true。 试试@Adam's answer如果这不是期望的行为。

关于java - 大于比较和交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9363419/

相关文章:

java - 如何使用 java Spark 提供 csv 文件?

java - 如何为 libGDX 设置 JAVA_HOME?

c - 无锁链表的性能比有锁链表差

java - 如何同时执行两个方法才能保证不延迟?

java - 使用 System.out.println(Thread.currentThread().getName() + ""+count);导致同步

go - 为什么此goroutine不调用wg.Done()?

java - 需要正则表达式的帮助来排除“”中的拆分字符串

java - 如何使用 Proguard 保留 InnerClass 中的特定字段

java - 使用 "Real"Executor 的 Guava Futures.transform 与使用 DirectExecutor 的 transformAsync

java - 并发 api 的 AbstractQueuedSynchronizer 构建 block 如何没有任何同步?