【问题标题】:While-loop stops checking if-statement? [duplicate]While-loop 停止检查 if 语句? [复制]
【发布时间】:2017-04-11 17:05:53
【问题描述】:

我有一个短暂的 while 循环,例如:

boolean a = false;
MyClass b = new MyClass();
b.b = false;

// b is used in other thread...

while(!a){
   if(b.b){
      throw new Exception("b is true");
   }
}

在这种情况下,a 永远不会变为真,但经过一些运行后,布尔变量 b.b 应该变为真。奇怪的是,while 循环从未离开,我的程序处于无限循环中。

我弄明白了原因并决定在循环中添加一个System.out.print 语句:

while(!a){
   if(b.b){
      throw new Exception("b is true");
   }
   System.out.println("there is something more to execute");
}

值得注意的是,我的代码工作正常。 while 循环在 if 语句上运行,直到 b.b 为真并且抛出异常离开循环。

会不会是在第一种情况下程序停止检查 if 语句,因为编译器认为没有必要再次检查?如果没有,谁能向我解释一下,为什么第一种情况不起作用,而第二种情况起作用?

【问题讨论】:

  • 线程之间如何同步b.b?
  • 当 b.b 在 if 中为真时,为什么不使用 break 或将 a 设置为 true?为预期行为抛出异常并不是好的设计。
  • 或许可以告诉我们 b 在另一个线程中是如何被使用的
  • 考虑注意您的代码。在您发布的代码中, b.b 永远不会成为真的。这意味着无限循环是唯一可能的结果。
  • @DwB 考虑关注问题中的代码。注意评论// b is used in other thread...。问题中没有显示另一个线程,但这并不意味着它不存在,并且假设它可以更改b.b 的值并不是一件容易的事。

标签: java multithreading if-statement while-loop infinite-loop


【解决方案1】:

如果您在多线程环境中工作,则需要将您的变量(可以访问多个线程)标记为volatile,否则不能保证当前线程看到另一个线程写入的结果。

换句话说,一个线程写入(更改)您的变量 a 的值,而另一个线程不能保证看到它(因为线程可能会复制/缓存变量),这会导致您的 while 循环不要打破。

我建议您查看here 并了解volatile 在多线程环境中的工作原理。下面的文字(强调我的)取自同一链接:

volatile 变量的更改始终对其他线程可见。当线程读取volatile 变量时,它不仅会看到 volatile 的最新更改,还会看到导致更改的代码的副作用。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
相关资源
最近更新 更多