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

标签 java multithreading atomic compare-and-swap

这是我想要的函数原型(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/

相关文章:

java - 防止 android Activity 重新加载

java - 使用 RandomAccessFile 的最佳方法是 Java

Java-允许一个线程更新值,其他线程等待并跳过关键部分

java - 绕过现场阴影

java - 中断异常与 while 循环中的 isInterrupted

python - 在python线程中关闭监听套接字

c# - 工作单元模式如何容纳对新聚合的引用?

c++ - C++ 标准甚至定义了 "lock-free"的含义吗?

linux - Intel-64 和 ia32 原子操作获取-释放语义和 GCC 5+

java - 计算列中的项目 vaadin