gpt4 book ai didi

java - 使用共享变量运行的并行编程 2 个线程

转载 作者:行者123 更新时间:2023-11-30 06:52:49 24 4
gpt4 key购买 nike

我有一个关于并发的问题,我刚刚写了一个运行 2 个线程的程序,指令如下:

Thread 1: increment by 1 the variable "num" till 1'000'000 with loop
Thread 2: same thing but decrementing

最后我收到了一个不想要的结果。是的,我知道我可以同步或尝试使用可重入锁,但问题是我无法理解所有这些不同的不良结果背后的原因。

我的意思是我使用的操作是可交换的,因此我们不关心顺序,所以如果这无关紧要,我们仍然应该获得 0,但事实并非如此!

谁能向我解释一下所有计算背后发生的事情,以便我能有所感受并立即识别这种情况?

编辑:由于我只是想了解主要概念,所以我认为没有必要放置代码。

代码:

class MyThread implements Runnable {
int id;
volatile static long num = 0;


MyThread(int id) {
this.id = id;

public void run() {
if (id == 0) {
for (int j = 0; j < 100000; ++j)
num++;}
} else {
for (int j = 0; j < 100000; ++j)
num--;}

在此之后我创建线程并运行它们:

    MyThread p = new MyThread(0);
MyThread q = new MyThread(1);
Thread t = new Thread(p);
Thread u = new Thread(q);
t.start();
u.start();
try {
t.join();
u.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

编辑2:我现在理解了这个概念,但我也想知道为什么将变量声明为 volatile 仍然给我错误的结果?

EDIT3:我考虑了一下,我认为这是因为糟糕的交错仍然会带来问题!

最佳答案

如果递增/递减操作不是原子的,你可能会以这种行为结束。
一个操作被认为是原子的如果它在系统的其余部分看来是瞬间发生的。 (参见 wikipedia)。

考虑以下情况:

  1. 线程 1 读取变量 x 中的值 n
  2. 线程 2 读取变量 x 中的值 n
  3. 线程 1 递增该值并将其存储在变量 x 中,该变量现在在 n+1 处求值。
  4. 线程 2 递减该值并将其存储在变量 x 中,该变量现在在 n-1 处求值。

但是您想要的是变量 x 仍然在 n 处求值。

我不知道 java 原语的具体情况,但看来您可以使用 AtomicInteger或使用 synchronized方法可以在这里解决您的问题。

关于java - 使用共享变量运行的并行编程 2 个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38347551/

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