【问题标题】:Executing a method call with Java atomic variables使用 Java 原子变量执行方法调用
【发布时间】:2020-08-24 09:52:22
【问题描述】:

假设我有一个这样的代码块

if (counter < 100) {
    synchronized (counter)
        if (counter < 100) {
            doSomething();
            counter.incrementAndGet();
        }
    }
}

其中计数器是AtomicLong。如何将此块转换为不再使用 synchronized 关键字并且仍然保持其正确性?还是不可能?

【问题讨论】:

  • 假设计数器 is 是 AtomicLong,您的代码无法编译。您不能使用 &lt; 运算符比较对象和整数。
  • “保持正确性”是什么意思——这段代码在什么方面是正确的?
  • 由于同步块内有“doSomething”,因此 AtomicLong 并不足以替代。您可以使用getAndUpdate 之一,但它有点小技巧。

标签: java multithreading java.util.concurrent


【解决方案1】:

这完全取决于您尚未显示的doSomething。它可能依赖于从同步块中调用,甚至可能无法并行化。

我认为可以接受的一个替代是

if (counter.getAndIncrement() < 100) {
    doSomething();
}

但假设doSomething 总是抛出异常。在您的代码中,计数器永远不会增加,因此条件将始终解析为真。在上面的例子中,它会被调用前 100 次,即使它们失败了也会算作一次迭代。

所以简而言之,为了让我们说是否保持正确性,那么您需要非常明确地定义正确的含义。

如果你不知道它是正确的意味着什么,那么你最好不要让它保持原样。

【讨论】:

  • 虽然不是我可以复制和粘贴的直接答案,但我从您的回答中得到了一个想法,它解决了我的问题。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
相关资源
最近更新 更多