【问题标题】:Why won't this 'if' statement run in a while loop without something else also happening in the while loop?为什么这个'if'语句不会在while循环中运行,而while循环中也没有发生其他事情?
【发布时间】:2015-09-30 02:40:34
【问题描述】:

我遇到了一个问题,即 if 语句仅在 while 循环中发生其他事情时才运行。

这是我要使用的代码:

public void load() throws IOException, InterruptedException {
    while (true) {
        if (findGame == true) {
            System.out.println(findGame);
        }
    }
}

这是简化的,但它显示了我的问题。基本上,当findGame == true 时,if 语句不会运行。我认为 if 语句没有运行的原因是变量没有被打印到控制台。

我做了一些测试,发现 if 语句运行的代码如下:

public void load() throws IOException, InterruptedException {
    while (true) {
        System.out.println("foo"); // New code added
        if (findGame == true) {
            System.out.println(findGame);
        }
    }
}

我的问题是为什么它适用于上面的代码而不是第一个?两者之间的唯一区别是有效的那个在 while 循环中添加了其他内容。

如果有什么不同,我上面显示的代码是在单独的线程中运行的。

【问题讨论】:

  • 只是一个注释,而不是if (findGame == true),你可以简单地写if (findGame),因为findGame已经是一个布尔值。
  • @Marv 这是一个很好的观点 - 谢谢 :) 我会在我的代码中改变它。

标签: java multithreading if-statement while-loop


【解决方案1】:

如果有什么不同,我上面显示的代码是在单独的线程中运行的。

这就是问题所在。您依赖一个线程设置的值在另一个线程中可见 - 如果不涉及内存屏障,就没有这样的保证。在您的第二个代码中,对println 的调用几乎肯定负责创建读取线程“查看”写入线程写入的值所需的内存屏障。不幸的是,记忆模型很难:(

如果您使用AtomicBoolean 而不仅仅是boolean 字段,您可能会发现第一个代码可以代替 - 但即便如此,紧密循环通常不是一个好主意。最好使用信号量或某种类似的信号,因此“读取”线程可以(闲置)等待,直到有变化。查看java.util.concurrent 中的SemaphoreCountDownLatch 等类。 (您可以只使用 waitnotify 来实现,但如果使用更高级别的抽象会更简单。)

【讨论】:

  • 这是一个绝妙的答案。谢谢你。我被困在这个问题上已经很久了,这已经解决了。我将研究您在最后一段中的建议,因为我对 Java 还很陌生,所以不完全理解您所说的。
  • @KianCross:我添加了一些可以帮助您调查的链接。
  • 使用volatile boolean,您可以在这种情况下特别实现线程安全,而不是较重的AtomicBoolean。
  • @Daniel:也许吧。在我看来,volatile 所做的确切的细节真的很复杂。我尽量避免它 - AtomicBoolean 实际上导致性能问题的机会(与这里的紧密循环的非常现实的问题相比)非常小。
猜你喜欢
  • 2019-07-07
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 2022-09-29
  • 2021-02-26
  • 2015-05-19
  • 2012-12-02
  • 1970-01-01
相关资源
最近更新 更多