gpt4 book ai didi

java - 使用原子整数时的竞争条件

转载 作者:行者123 更新时间:2023-12-02 01:27:47 25 4
gpt4 key购买 nike

我正在学习java.util.concurrent.atomic包并尝试Atomic Integer。根据我的理解,原子包有助于编写无锁代码,而不是使用同步块(synchronized block)。因此,为了测试我的理解,我编写了以下代码:

public class Test{

private final AtomicInteger ai;

public void increment() {
int oldVal = ai.get();

while(!ai.compareAndSet(oldVal, oldVal+1)) {
oldVal = ai.get();
}
}

public int incrementModified() {
return ai.incrementAndGet();
}

public int get() {
return ai.get();
}

public static void main(String[] args) {
Test pc = new Test(5);

Runnable r1 = () -> {
pc.increment();
};

Runnable r2 = () -> {
pc.increment();
};

Runnable r3 = () -> {
pc.increment();
};

Thread t1 = new Thread(r1);

Thread t2 = new Thread(r2);

Thread t3 = new Thread(r3);

t1.start();
t2.start();
t3.start();

System.out.println(pc.get());

}

当我执行上述代码时,我期望输出为 8,但我得到的输出为 7/8。然后我什至使用了内置的 incrementAndGet() 方法,并且在运行程序多次后仍然得到相同的输出。

根据我的理解,由于原子可以用作同步块(synchronized block)的替代品,并且它通过使用 CAS(比较和设置指令)使增量操作原子化,所以我应该始终得到输出 8。

但是由于我得到了不同的输出,我假设存在竞争,因此 o/p 在 7/8 之间变化。

有人可以指出我在上面的代码中犯的错误或者纠正我对 Java 原子类的理解吗?

编辑:

正如评论中所指出的,我没有使用join(),因此得到了错误的结果,因为主线程正在请求该值,而某些线程可能仍在操作中间。我添加了它,经过多次测试后,我可以看到预期的结果。

最佳答案

打印值的行与其他 3 个线程同时执行。如果你想确保它在 3 个线程运行后执行,那么你需要在这些线程上 join() 。

关于java - 使用原子整数时的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56614249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com