简体   繁体   English

为什么这个'if'语句不会在while循环中运行而没有其他东西也会在while循环中运行?

[英]Why won't this 'if' statement run in a while loop without something else also happening in the while loop?

I'm having a problem where an if statement is only running if there is something else happening before it in the while loop. 我遇到一个问题,如果在while循环中发生了其他事情,if语句才会运行。

Here is the code I want to use: 这是我想要使用的代码:

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

That is simplified but it shows my problem. 这是简化但它显示了我的问题。 Basically, when findGame == true , the if statement does not run. 基本上,当findGame == true ,if语句不会运行。 The reason I don't think the if statement is running is because the variable is not being printed out to the console. 我不认为if语句正在运行的原因是因为该变量没有打印到控制台。

I did some tests and found that the if statement ran with the following code: 我做了一些测试,发现if语句使用以下代码运行:

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

My question is why does it work with the above code but not the first one? 我的问题是为什么它与上面的代码一起工作但不是第一个? The only difference between the two is that the one that works has something else added to the while loop. 两者之间的唯一区别是,工作的那个有其他东西添加到while循环。

If it makes a difference, the code I've shown above is running in a separate thread. 如果它有所不同,我上面显示的代码在一个单独的线程中运行。

If it makes a difference, the code I've shown above is running in a separate thread. 如果它有所不同,我上面显示的代码在一个单独的线程中运行。

And that's the problem. 这就是问题所在。 You're relying on a value set by one thread to be visible in another - and there's no such guarantee without memory barriers being involved. 您依赖于一个线程设置的值在另一个线程中可见 - 并且没有涉及内存屏障的保证。 In your second code, the call to println is almost certainly responsible for creating the memory barriers required for the reading thread to "see" the value written by the writing thread. 在你的第二个代码中,对println的调用几乎肯定是创建读取线程“看到”写入线程写入的值所需的内存障碍。 Memory models are hard, unfortunately :( 记忆模型很难,不幸的是:(

If you use AtomicBoolean instead of just a boolean field, you may well find the first code works instead - but even so, a tight loop is generally a bad idea. 如果您使用AtomicBoolean而不仅仅是boolean字段,您可能会发现第一个代码正常工作 - 但即便如此,紧密循环通常也是一个坏主意。 It would be better to use a semaphore or some similar kind of signalling, so the "reading" thread could just wait (idly) until there's a change. 最好使用信号量或类似的信号,因此“读取”线程可以等待(空闲)直到发生变化。 Look into java.util.concurrent for classes such as Semaphore and CountDownLatch . 查看java.util.concurrentSemaphoreCountDownLatch等类。 (You can do it with just wait and notify , but it'll be simpler if you use higher-level abstractions.) (您只需waitnotify就可以做到这一点,但如果您使用更高级别的抽象,它会更简单。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM