一个简单的Java竞争条件
我只想写一个竞赛条件的例子: MyParallelClass.java:一个简单的Java竞争条件,java,race-condition,Java,Race Condition,我只想写一个竞赛条件的例子: MyParallelClass.java: 公共类MyParallelClass实现java.lang.Runnable{ 公共整数计数器=0; @凌驾 公开募捐{ 如果(test.globalVar>0){ 对于(int i=0;i
公共类MyParallelClass实现java.lang.Runnable{
公共整数计数器=0;
@凌驾
公开募捐{
如果(test.globalVar>0){
对于(int i=0;i<1000000;i++){
计数器++;
}
test.globalVar--;
}
}
}
test.java:
公共类测试{
公共静态int globalVar;
公共静态void main(字符串[]args){
globalVar=1;
MyParallelClass a=新的MyParallelClass();
MyParallelClass b=新的MyParallelClass();
新线程(a).start();//线程a
新线程(b).start();//线程b
系统输出打印LN(globalVar);
}
}
我认为会发生什么:
我认为如果线程A在线程B启动之前完全执行,那么这可以输出0
变量test.globalVar
也可以这样操作:
Thread A - Thread B
checks if (globalVar > 0)
looping ... checks if (globalVar > 0)
looping ... execute all four bytecode commands of "test.globalVar--;"
execute test.globalVar--;
因此,test.globalVar
的值应该是-1
因此,要么执行其中一个if语句,要么同时执行这两个语句
实际发生的情况:
我得到了
0
和1
作为main方法的输出。为什么我得到0
和1
而不是0
和-1
?好问题。我认为您需要运行更多测试。:-)
您可以尝试将Runnable类中的循环更改为以随机毫秒数(500-1000)休眠。循环10次。看看你是否没有达到预期的比赛状态
我认为大多数电脑都太快了。很简单,循环可能没有做足够的工作来导致线程切换
我喜欢这类问题,因为我总是遇到这样的问题。好问题。我认为您需要运行更多测试。:-) 您可以尝试将Runnable类中的循环更改为以随机毫秒数(500-1000)休眠。循环10次。看看你是否没有达到预期的比赛状态 我认为大多数电脑都太快了。很简单,循环可能没有做足够的工作来导致线程切换
我喜欢这类问题,因为我总是遇到这样的错误。您将
globalVar
递减两次。结尾处的globalVar
的可能值为:
-如果一切正常,并且两个线程在打印之前正确地减小了值-1
:0
- 如果只有一个线程设法减少变量,而第二个线程在打印之前没有设法完成
- 如果同时减小了
globalVar
:1
- 如果
在两个线程完成之前成功执行(很可能)。确实修改了System.out.println()
,但它已经打印出来了globalVar
- 由于可见性问题,
线程看到原始的main
值,而不是由不同线程修改的值。您需要某种同步或globalVar
关键字来立即(或永远)查看其他线程所做的更改volatile
- 如果
globalVar
。结尾处的globalVar
的可能值为:
-如果一切正常,并且两个线程在打印之前正确地减小了值-1
:0
- 如果只有一个线程设法减少变量,而第二个线程在打印之前没有设法完成
- 如果同时减小了
globalVar
:1
- 如果
在两个线程完成之前成功执行(很可能)。确实修改了System.out.println()
,但它已经打印出来了globalVar
- 由于可见性问题,
线程看到原始的main
值,而不是由不同线程修改的值。您需要某种同步或globalVar
关键字来立即(或永远)查看其他线程所做的更改volatile
- 如果
System.out.println(globalVar);
不等待线程完成。线程在该点可能是完整的,也可能不是完整的。因此,该值可以是0
、1
或-1
,具体取决于两个线程是否都已完成、一个线程是否已完成或两个线程都未完成
要进行更好的测试,-在线程中使用
Thread.sleep()
,以确保存在延迟-在不同的线程中使用不同的延迟,以便更好地可视化竞争条件。
-您可能还希望在线程中打印变量的值。这样,您就有了三个线程(A、B和主线程),并且可以获得更好的可视化效果。 不等待线程完成。线程在该点可能是完整的,也可能不是完整的。因此,该值可以是
0
、1
或-1
,具体取决于两个线程是否都已完成、一个线程是否已完成或两个线程都未完成
要进行更好的测试,-在线程中使用
Thread.sleep()
,以确保存在延迟-在不同的线程中使用不同的延迟,以便更好地可视化竞争条件。
-您可能还希望在线程中打印变量的值。这样,您就有了三个线程(A、B和主线程),并且可以获得更好的可视化效果。如果在任何一个线程减小值之前打印值,则可以得到1。如果在任何一个线程减小值之前打印值,则可以得到1