【问题标题】:Is a Thread-safe method with two AtomicIntegers possible?具有两个 AtomicInteger 的线程安全方法是否可能?
【发布时间】:2019-11-24 18:28:38
【问题描述】:

我想编写一个线程安全的方法 sum() 但我不确定是否可以使用两个 AtomicInteger 来确保安全,还是必须使用同步块?

class A {

   private AtomicInteger a = new AtomicInteger();
   private AtomicInteger b = new AtomicInteger();

   public void sum(int c) {
      a.set(a.get() + b.get() + c);
   }
}

【问题讨论】:

  • 您问它是否“线程安全”,但“线程安全”对您意味着什么?变量abc 之间是否存在特殊关系?是否可以通过另一个线程的操作来更改它们中的任何一个?如果您相加的ac 是另一个线程执行其操作之前的值,但b 的值是 after其他线程做了它的事?线程安全主要是关于保留程序中不同共享变量之间的重要关系,只有程序的作者才能说出它们是什么。

标签: java multithreading synchronized atomicinteger


【解决方案1】:

The rules for evaluation order in Java 表示您将始终遵循一系列不重叠的锁:A (get) -> B (get) -> A (set)。所以你不会有任何阻塞问题,因为锁不会相互干扰。但是请注意,存在一种竞争条件:线程 1 可能先读取 A,然后再读取 B。在线程 1 设置 A 之前,线程 2 可以读取 A 和 B。最终值将是其中一个线程' 结果总和,但另一个将丢失。

【讨论】:

    【解决方案2】:

    AntomicInteger 有特定的方法来处理这个问题。你不需要打破 AtomicInteger 这个词,它是线程安全的。 只需检查 AtomicInteger 的 JavaDocs 就会向您展示可以用于此的方法,例如 AtomicInteger.getAndAdd

    【讨论】:

    • 谢谢,应该是这样的吧? a.getAndAdd(b.get() + c);
    • 没错,getAndAdd 解决了你例子中的线程问题。但是查找 getAndAdd 以便您了解它是如何工作的。它返回旧值,而“a”将包含总和。
    猜你喜欢
    • 1970-01-01
    • 2021-08-25
    • 2019-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多