只需多次运行代码,在这些幸运时刻之一,您将能够看到线程干扰在起作用。
在这种情况下很少观察到,因为它是一个小程序并且没有发生太多事情。如果你制作多个递增和递减线程,线程干扰将更容易观察。
class Counter {
private int c = 0;
public void increment() {c++;}
public void decrement() {c--;}
public int value() {
return c;
}
public static void main(String[] args) {
Counter x = new Counter();
Runnable r1 = new Runnable() {
@Override
public void run() {
x.increment();
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
x.decrement();
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
System.out.println(x.c);
}
}
编辑:我决定添加多线程案例,我无法抗拒
编辑2:这是第二次编辑。多线程案例,因为这造成了超出这个问题范围的问题,我决定删除它。以前我正在制作一个线程数组并运行它们。相反,最好显示一个一个做很多增量的线程和另一个做很多减量的线程。
我使用了 Thread.Sleep() 导致主线程进入睡眠状态,这将确保在两个线程都完成对它的操作后打印 c 。
class Counter {
private int c = 0;
public void increment() {
for (int i = 0; i < 10000; i++) {
c++;
}
}
public void decrement() {
for (int i = 0; i < 5000; i++) {
c--;
}
}
public int value() {
return c;
}
public static void main(String[] args) {
Counter x = new Counter();
Runnable r1 = new Runnable() {
@Override
public void run() {
x.increment();
}
};
Runnable r2 = new Runnable() {
@Override
public void run() {
x.decrement();
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!(t1.isAlive() && t2.isAlive()))
System.out.println(x.c);//expected answer 5000
}
}
注意:同步增量/减量方法给出正确答案。自己尝试。