isInvalid(value), () -> createValid(-6ren">
gpt4 book ai didi

java - 如何 "' 像 CAS 一样以原子方式验证和惰性交换?

转载 作者:行者123 更新时间:2023-11-30 10:26:58 26 4
gpt4 key购买 nike

这是我想要的函数原型(prototype):

atomicReference.validateAndSwap(value -> isInvalid(value), () -> createValid());

它假定从多个线程调用。
第二个 lambda 仅在第一个返回 true 时被调用。
首先(如果第一个返回 true,则加上第二个)lambda 调用应该是单个原子操作。

甚至可以不用synchronized来实现?
是否有类似功能的现成解决方案?
我是否有错误的思维方式并错过了什么?

最佳答案

我不确定您说“第一个(如果第一个返回 true 则加上第二个)lambda 调用应该是单个原子操作。”的意思是否正确。原子引用的要点是更新函数评估可能重叠,因此不应有干扰,但会像原子一样运行,因为当评估重叠时,只有一个可以通过 CAS 成功,另一个可以成功必须根据新值重复。

如果你想要真正的原子计算,使用 Locksynchronized 是不可避免的。如果你有适当的非干扰函数并且想要像原子一样实现更新,它可以像这样实现

Value old;
do old = atomicReference.get();
while(isInvalid(old) && !atomicReference.compareAndSet(old, createValid()));

由于在这种特定情况下,createValid() 函数不依赖于旧值,我们可以避免在竞争情况下重复求值:

Value old = atomicReference.get();
if(isInvalid(old)) {
Value newValue = createValid();
while(!atomicReference.compareAndSet(old, newValue)) {
old=atomicReference.get();
if(!isInvalid(old)) break;
}
}

所有这些都假设对象的有效性不能在两者之间改变。否则,锁定或同步是不可避免的。

请注意,Java 8 的更新方法遵循相同的原则。所以你可以写

atomicReference.updateAndGet(old -> isInvalid(old)? createValid(): old);

实现相同,但它也不是真正的原子,而是如果更新函数的并发评估没有干扰,则表现得好像是原子的。

关于java - 如何 "' 像 CAS 一样以原子方式验证和惰性交换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45486206/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com