Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 while循环是否会在一段时间后停止执行?_Java_Multithreading_While Loop_Infinite Loop_Println - Fatal编程技术网

Java while循环是否会在一段时间后停止执行?

Java while循环是否会在一段时间后停止执行?,java,multithreading,while-loop,infinite-loop,println,Java,Multithreading,While Loop,Infinite Loop,Println,所以我现在正在尝试多线程,因为我对Java还是相当陌生的。现在,我有多个线程,它们都影响同一个长变量。然而,似乎在检查if语句之后,while循环停止执行(如中所示,它无限循环)。如果我只是在while循环中打印一些东西,它确实可以工作 不起作用: while(true){ if(longVariable < 2) break; } while(true){ if(长变量

所以我现在正在尝试多线程,因为我对Java还是相当陌生的。现在,我有多个线程,它们都影响同一个长变量。然而,似乎在检查if语句之后,while循环停止执行(如中所示,它无限循环)。如果我只是在while循环中打印一些东西,它确实可以工作

不起作用:

while(true){
  if(longVariable < 2)
    break;
}
while(true){
if(长变量<2)
打破
}
不知何故,它起作用了:

while(true){
  System.out.println("hi");
  if(longVariable < 2)
    break;
}
while(true){
System.out.println(“hi”);
if(长变量<2)
打破
}

这是为什么?

当您有一个非易失性变量,而该变量没有被线程更新时,可以自由地内联它

在第一种情况下,一旦JIT编译了代码,它可能不再读取值,而是使条件始终为true

在第二种情况下,您有一个线程安全操作
println
on
System.out
是一种
synchronized
方法。这增加了读写屏障,并防止JIT优化读取操作

如果你试着这样做,它也会起作用

while(true){
  synchronized("hi") { } // does nothing but add memory barriers.
  if(longVariable < 2)
    break;
}
while(true){
synchronized(“hi”){}//只会添加内存障碍。
if(长变量<2)
打破
}
它还使代码的速度降低了1000倍以上,因此在您尝试停止线程时,该方法可能还没有JIT

简单的解决方案是将变量
设置为volatile
,每次都以线程安全的方式读取

while(true){
  if(longVariable < 2)
    break;
}
如果执行时
longVariable
至少为2,则它将无限循环,因为任何东西都不能更改
缓存的

您必须给编译器一个提示,说明不允许这种重写。它与JVM上的
System.out.println
一起工作,因为它恰好是通过同步实现的(这是常见的,但不是必需的)。这会插入内存屏障,这意味着
longVariable
的缓存值无效,必须重新读取

但这并不能保证有效。要使其正常工作,请声明变量volatile:

volatile long longVariable
这会阻止缓存其值

或者使用类似于
AtomicLong
的变量,而不是普通的
long
变量

或者,最麻烦的是,使用显式同步(确保变量的所有读写都在同一个“某物”上同步):

长v;
同步的(某物){
v=长变量;
}
如果(v<2)。。。

我猜
longVariable
没有声明为volatile?向我们展示代码的其余部分编辑问题以包含更多代码您是否更改过
longVariable
的值?什么时候,怎样?
longVariable
的初始值是多少?能否显示完整的代码
volatile long longVariable
long v;
synchronized (something) {
  v = longVariable;
}
if (v < 2) ...