gpt4 book ai didi

java - java中多线程的意外答案

转载 作者:行者123 更新时间:2023-12-01 17:00:44 24 4
gpt4 key购买 nike

这是我的代码,使用 4 个线程将变量“res”求和 4*10^7 次:

class MathSin extends Thread {

public double a;

public MathSin(int degree) {
a = degree;
}

@Override
public void run() {

for (int i = 0; i < Math.pow(10., 7); i++)
MathThreads.res++;

}
}

class MathThreads {
public static double res = 0;

public static void main(String args[]) {
MathSin st = new MathSin(8);
MathSin ct = new MathSin(8);
MathSin tt = new MathSin(8);
MathSin qt = new MathSin(8);
st.start();
ct.start();
tt.start();
qt.start();
try { // wait for completion of all thread and then sum
st.join();
ct.join(); // wait for completion of MathCos object
tt.join();
qt.join();
System.out.println(res);
} catch (InterruptedException IntExp) {
}
}
}

以下是一些答案:

1.8499044E7

2.3446789E7
.
.
.

我期望得到 3.0E7 但得到另一个不同的答案。

如何解决这个问题?

最佳答案

问题是什么?

您在更新 static 时观察竞争条件变量res .

MathThreads.res++

相当于:

double tmp = MathThreads.res;
MathThreads.res = tmp + 1;

现在,如果两个线程同时读取 tmp 的值,会发生什么情况? ,并且都更新 restmp + 1 ?好吧,只是忘记了一个增量:res结束是 tmp + 1而不是tmp + 1 + 1 !

因此,有 4 个线程更新 res同时,您最终会遇到未定义的行为:无法预测 res 的最终值因为这些竞争条件。两次执行相同的代码将给出不同的答案。

如何解决这个问题?

为了使你的代码线程安全,你需要使用 res 的线程安全结构。 :可以同时更新和访问的结构。

就您而言,AtomicLong似乎是完美的选择:

public static AtomicLong res = new AtomicLong(0);

并在 run 方法中:

for (int i = 0; i < Math.pow(10., 7); i++) {
MathThreads.res.incrementAndGet();
}

关于java - java中多线程的意外答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27769934/

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