Java 8 实现比较和交换(不是比较和设置!)

李浩穎*_*李浩穎 1 java atomic atomicreference compare-and-swap java-8

在java 17中,AtomicReferencecompareAndExchange类似于 的方法compareAndSet,但它不返回布尔值,而是返回原子操作之前的值。我需要它来实现自定义并发结构。

由于项目的限制,我只能使用 Java 8 功能。一些挖掘揭示了VarHandle其中有compareAndExchange。但是,VarHandle需要 Java 9。

因此,看来我必须compareAndExchange亲自实施了。但如何利用现有方法高效地做到这一点呢?(那么compareAndExchangeWeak版本呢?)

(顺便说一句,我不能依赖任何第三方库)

Ste*_*n C 5

这很接近,但至少在一种情况下有明显的差异:

V witness = ref.get();
if (ref.compareAndSet(oldValue, newValue)) {
    return oldValue;
} else {
    return witness;
}
Run Code Online (Sandbox Code Playgroud)

如果witness != oldValue,则该witness值不一定是我们进行比较和设置时参考的正确值。

然而,尚不清楚该值是否有用......因此“接近但不完全正确”可能就足够了。如果 100% 正确compareAndExchange,则返回的结果不会告诉调用者引用现在的witness状态。当调用者尝试使用返回值时,另一个线程可能已经更改了引用。

例如,这可以返回一个匹配的值,而oldValue无需完成存储。例如,如果多个线程同时运行该值,并且oldValueref具有该值时,它们都可以加载witness = oldValue,但只有一个线程会成功执行 CAS。因此,您无法安全地使用返回值来确定您的 CAS 是否“赢得了更新竞赛” ref。你需要不断地bool从中返回价值compareAndSet

我认为在不使用锁的情况下不可能进行精确的模拟compareAndExchange......这将在很大程度上破坏使用AtomicReference.