我正在经历多线程中的种族条件,并想到创造一种导致竞争条件的情况,我写了一个简单的程序,但每次我得到正确的结果。需要知道这种情况是否适合种族条件。
代码如下:
exec /path/to/Emacs.app "$@"
//我的机器输出总是20,Win7 32位。
答案 0 :(得分:0)
您的代码确实模拟了竞争条件,因为添加涉及读写。但是要真正展示这里的竞争对手,你需要一些非常不幸的调度,因为所有的线程都是补充。您可能想尝试在不同的计算机上运行它,或者让某些线程执行其他操作,例如删除或减法。
另一种选择是通过在Thread.sleep(random)
中添加addTo()
来确保竞争条件。
答案 1 :(得分:0)
您的程序因竞争条件而受到极少的可能性,因为所有线程都会添加到字段 a ,因此订单会影响最终结果。 只有当两个线程读取 a 的相同值时,首先分配一个新值然后第二个分配一个新值,你可能会失去"增量。
这是一个更频繁遭受竞争条件的修改版本:
public class Step4 {
public int getA() {
return a;
}
public void addToA(int number) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<number;i++)
this.a = this.a + 1;
}
public void multiplyA(int number) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.a = this.a * number;
}
int a = 2;
static Step4 s4;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
s4 = new Step4();
doRun();
System.out.println("*******");
}
}
private static void doRun() throws InterruptedException {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
s4.addToA(5);
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
s4.multiplyA(3);
}
});
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
s4.addToA(6);
}
});
Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
s4.addToA(4);
}
});
thread1.start();
thread2.start();
thread3.start();
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
System.out.println(s4.getA());
}
}
我为这两个动作添加了100毫秒的睡眠时间,以增加获得不同结果的机会。 大多数情况下,结果将是31,但在其他时间可能是17,21或51。