Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
一个简单的Java竞争条件_Java_Race Condition - Fatal编程技术网

一个简单的Java竞争条件

一个简单的Java竞争条件,java,race-condition,Java,Race Condition,我只想写一个竞赛条件的例子: MyParallelClass.java: 公共类MyParallelClass实现java.lang.Runnable{ 公共整数计数器=0; @凌驾 公开募捐{ 如果(test.globalVar>0){ 对于(int i=0;i

我只想写一个竞赛条件的例子:

MyParallelClass.java

公共类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