【发布时间】:2016-07-13 09:21:00
【问题描述】:
我有一个关于并发的问题,我刚刚编写了一个运行 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:我考虑过,我认为这是因为糟糕的交错仍然会产生问题!
【问题讨论】:
-
代码在哪里?
-
"an undesired result" 您的问题中没有给出您想要或不想要的结果,因此很难理解您的问题。
-
这个问题已经回答了很多次了,但是我建议你如果能自己解决的话会学到更多。答案并不复杂。提示:分解
--和++真正要做的事情。 -
@AndyTurner 期望的结果写成 (0),这意味着不期望的结果与 0 不同(每次运行后它给出不同的结果)。但是我现在还是附上了代码!
-
@AndyTurner 虽然没有指定,但这个问题已经被问了很多次,假设它是同一个问题是很安全的。 ;)
标签: java multithreading concurrency parallel-processing