我正在尝试重现线程干扰场景.. 但有些不对劲。请帮我理解什么
主要的
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
for (int i = 0; i < 1000000; i++) {
new T1(c).start();
new T2(c).start();
}
System.out.println(c.value()); // <-- Expect this to sometimes not be 0
}
柜台
class Counter {
private int c = 0;
public void increment() { // <-- intentionally not synchronized
c++;
}
public void decrement() { // <-- intentionally not synchronized
c--;
}
public int value() {
return c;
}
}
线程 1
public class T1 extends Thread {
Counter c;
T1(Counter c) {
this.c = c;
}
public void start() {
c.decrement(); // <-- Decrement
}
}
线程 2
public class T2 extends Thread {
Counter c;
T2(Counter c) {
this.c = c;
}
public void start() {
c.increment(); // <-- Increment
}
}
当我开始 1000000 个线程时,每个线程都在代码的非同步部分上运行,我希望一些操作会重叠。
当两个在不同线程中运行但作用于相同数据的操作交错时,就会发生干扰。这意味着这两个操作由多个步骤组成,并且步骤的顺序重叠。
Counter 实例上的操作似乎不可能交错,因为 c 上的两个操作都是单个简单的语句。但是,即使是简单的语句也可以由虚拟机转换为多个步骤。我们不会检查虚拟机采取的具体步骤——知道单个表达式 c++ 可以分解为三个步骤就足够了:
检索 c 的当前值。将检索到的值增加 1。将增加的值存储回 c。
请问我错过了什么?