java - 为什么这段代码线程安全?

标签 java multithreading

我正在准备OCP考试,我在模拟考试中发现了这个问题:

给定:

class Calculator {
    private AtomicInteger i = new AtomicInteger();
    public void add(int value) {
        int oldValue = i.get();
        int newValue = oldValue + value;
        System.out.print(i.compareAndSet(oldValue,newValue));
    }
    public int getValue() {
        return i.get();
    }
}

您可以做些什么来使此类线程安全?

令我惊讶的是,答案是: “类计算器是线程安全的”

一定是我没有正确理解这个概念。据我了解,当所有方法在线程并发下按预期工作时,一个类是线程安全的。现在,如果两个线程同时调用 getValue(),然后调用 add() 传递一个不同的值,然后它们再次调用 getValue(),“第二个”线程将看不到它传递的值增加。

我知道 oldValue 和 newValue 作为局部变量存储在方法堆栈中,但这并不能阻止第二次调用 compareAndSet 会发现 oldValue 不是当前值,因此不会添加新值。

我在这里错过了什么?

最佳答案

根据 JCIP

A class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, and with no additional synchronization or other coordination on the part of the calling code.

虽然没有线程安全的定义,也没有类的规范,但在我看来,根据 Calculator 类中 add 方法的任何合理定义,它如果 AtomicInteger i 的值在任何情况下都增加,则“不考虑执行的调度或交错”是“正确的”。

因此,在我看来,根据这个定义,该类不是线程安全的。

关于java - 为什么这段代码线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34832475/

相关文章:

c - 线程程序从线程返回错误(?)结果

c++ - 为什么 Ubuntu 中使用 pthread 的单线程比多线程更快?

java - Java 中的 Haskell 风格内存

Java-如何解决我的 TicTacToe 游戏的方法无法应用于给定类型错误?

java - 如何提高使用 JAXBContext.newInstance 操作的应用程序的性能?

java - 并发线程化图像处理类

c++ - 栅栏实际上如何在 C++ 中工作

java - 测试对事务服务的同时调用

java - 来自另一个类中的对象的引用变量

java - 什么时候应该使用 EJB 事务属性 'Mandatory' 和 'Never'