两个线程在不同步的情况下访问的计数器的最小值 [英] minimum value of a counter accessed by two threads without synchronization
问题描述
我在一次采访中被告知,运行以下代码后 counter 的最小值是 2.这怎么可能?
I've been told in an interview that the minimum value for counter after running the following code is 2. How is that possible?
class ThreadsConflict {
private static int counter = 0;
public static void main(String[] args) throws InterruptedException{
Thread t1 = new A();
Thread t2 = new A();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(counter);
}
static class A extends Thread {
public void run() {
for(int i = 0; i < 10; i++) {
counter++;
}
}
}
}
我可以理解为什么如果它们交错并且 ++ 运算符冲突,为什么它会是 10,但它怎么可能会低于 10?
I can understand why it will be 10 if they are interleaved and the ++ operator is conflicting but how is it possible that it will be under 10?
推荐答案
那是因为交错发生在非原子操作之间,所以 counter++
可以在中间被中断,有点:
That's because interleaving occurs between non atomic operations so counter++
can be interrupted in the middle, sort of:
int tmp = counter;
/* threads gets interrupted here */
counter = tmp + 1;
这可能会导致极端情况:
This may lead to corner case situations as:
- 线程 A 读取 0
- 线程 B 读 0 写 1
- 线程 B 读 1 写 2
- ...
- 线程 B 读取 8 并写入 9
- 线程 A 写入 1
- 线程 B 读取 1
- 线程 A 读 1 写 2
- 线程 A 读取 2 并写入 3
- ...
- 线程 A 读取 9 并写入 10
- 线程 A 完成
- 线程 B 写入 2
- 线程 B 完成
请注意,这是因为 i
用作条件,所以正好完成 10 次迭代,如果您直接使用 counter
那么您将保证在至少 10 个.
Mind that this is because i
is used as a condition so exactly 10 iterations are done, if you were using directly counter
then you'll be guaranteed to have at least 10.
这篇关于两个线程在不同步的情况下访问的计数器的最小值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!