当标志在不同线程中更改时,while 循环未结束 [英] While loop not ending when flag changed in different thread

查看:28
本文介绍了当标志在不同线程中更改时,while 循环未结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Java 程序的 main 方法中运行了一个 while 循环.该循环应该一直运行,直到在程序的 keyPressed 方法中将布尔标志变量设置为 true(我将程序作为 KeyListener 添加到 JFrame).

I have a while loop running in my Java program's main method. The loop is supposed to run until a boolean flag variable is set to true in the program's keyPressed method (I added the program as a KeyListener to a JFrame).

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;

public class ThreadWhile implements KeyListener {
    private boolean flag = false;

    public static void main(String[] args) {
        //Set up key listening on a dummy JFrame
        JFrame frame = new JFrame("Key Detector 9000");
        frame.setVisible(true);
        ThreadWhile tw = new ThreadWhile();
        frame.addKeyListener(tw);

        System.out.println("Looping until flag becomes true...");
        while(!tw.flag) {
            //Commenting the println out makes the loop run forever!
            System.out.println(tw.flag); 
        }
        System.out.println("Flag is true, so loop terminated.");
        System.exit(0);
    }

    public void keyPressed(KeyEvent e) {
        flag = true;
        System.out.println("flag: " + flag);
    }

    public void keyReleased(KeyEvent e) {}
    public void keyTyped(KeyEvent e) {}
}

我的理解是 keyPressed 方法在它们自己的线程中执行,所以当我按下一个键时,变量 'flag' 应该设置为 true,并且在 main 方法中运行的 while 循环应该结束.

It is my understanding that keyPressed methods execute in their own threads, so it seems like when I hit a key, the variable 'flag' should be set to true, and the while loop running in the main method should end.

然而,当我运行这个程序时,循环将永远运行,即使我们可以看到 'flag' 变量被正确设置为 true!奇怪的是,如果我在 while 循环中插入一个标志"变量的快速 System.out.println 回显,程序的行为是正确的,但显然我不想在循环中打印任何内容.

HOWEVER, when I run this program, the loop runs forever, even though we can see that the 'flag' variable is being set to true correctly! Oddly, the program behaves correctly if I insert a quick System.out.println echo of the 'flag' variable inside the while loop, but obviously I don't want to print anything out in the loop.

我猜这个问题可能是由于 Java 编译器试图优化空的 while 循环到它停止实际检查标志"变量的程度?有没有人有关于使这项工作正常工作的建议,或者可能有一些更漂亮的基于并发的方法来使主线程暂停,直到 keyPressed 线程执行?

I'm guessing this problem might be a result of the Java compiler trying to optimize the empty while loop to the point where it stops actually checking the 'flag' variable? Does anyone have suggestions for making this work correctly, or perhaps some more nifty concurrency-based approaches to making the main thread pause until the keyPressed thread executes?

谢谢!

推荐答案

您需要声明标志 volatile,否则编译器可以优化您的代码并跳过标志的读取.

You need to declare the flag volatile, otherwise the compiler can optimize your code and skip the reads of the flag.

这篇关于当标志在不同线程中更改时,while 循环未结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆