【问题标题】:If compareAndSet fails, is the code below still executed?如果 compareAndSet 失败,下面的代码是否仍然执行?
【发布时间】:2026-01-14 19:25:01
【问题描述】:

我有一个非常愚蠢的问题。 如果我使用 AtomicReferences compareAndSet 这样

    original.set(atomic.get());
    long next = some new value
    atomic.compareAndSet(original.get(), next);
    ....more code....

如果比较失败(即原子已被另一个线程更新),仍然会更新更多代码。 我试图找出作业中的错误,这是我唯一能想到的,我已经尝试了几个小时。

附: 奇怪的是,如果我在这段代码上使用同步 它在我的笔记本电脑上给了我正确的答案,但在我的桌面上却没有

【问题讨论】:

  • 这是一种和其他方法一样的方法。继续执行下一条语句。如果您希望有条件地执行更多代码,请添加 if 语句。
  • 您需要使用条件语句检查 compareAndSet 是否成功。见最后一节 - tutorials.jenkov.com/java-util-concurrent/atomicboolean.html
  • @MangatRaiModi 谢谢,这修复了我的代码。知道为什么这可以在我的笔记本电脑上同步但不能在 PC 上使用吗?
  • 是的,它通常与循环一起使用。但单独并不能保证太多。
  • @MangatRaiModi 谢谢。是的,多亏了你们两个,我才发现了这个错误。我错误地认为这会一直尝试直到正确。您提供的书籍链接实际上是我的教科书,很好。这个网站也很棒,它实际上帮助我完成了上周关于可重入锁的作业。我也喜欢打包书。

标签: java concurrency atomic compare-and-swap


【解决方案1】:

MangatRaiModi 和 SotiriosDelimanolis 让我走上了正确的道路。 一个简单的修复:

    original.set(atomic.get());
    long next = some new value
    while(!atomic.compareAndSet(original.get(), next))
    {
      do above again
    }
    ....more code....

做到了。 仍然不确定同步如何在我的笔记本电脑上解决这个问题,但不是在我的桌面上。 我猜它会减慢移动芯片上的线程速度,以便它们可以按顺序运行(就像打印语句一样)。 不过我可能错了。

【讨论】:

  • synchronised 和 compareAndSet 在语义上有很大的不同。同步块取一个锁,这样没有其他线程可以执行那段代码。所以它有效。 CompareAndSet 实际上检查值是否已从原始值更改,如果是,则未设置。这是一个原子操作。并发很棘手,很容易导致错误。我强烈建议做一些在线课程或阅读它。试试这两个amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601tutorials.jenkov.com/java-concurrency/index.html
  • @MangatRaiModi 谢谢,我这样做实际上是我的并发和并行编程单课程作业的一部分,它是关于实现随机数的线性同余生成器。其中一个课程教科书实际上是您提供的第一个链接。我能够使用锁和同步来做到这一点,现在第三部分是使用原子变量。
最近更新 更多