If there is no body, won’t the while loops in Java check their conditions?

In this example, I have a simple JFrame that contains a JButton. JFrame bound with actionlistener The acitonlistener simply changes a boolean flag that allows the program to complete

public class Test {
    public static void main(String[] args){
        final boolean[] flag = new boolean[1];
        flag[0] = false;
        JFrame myFrame = new JFrame("Test");
        JButton myButton = new JButton("Click Me!");
        myButton.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.out.println("Button was clicked!");
                flag[0] = true;
            }
        });
        myFrame.add(myButton);
        myFrame.setSize(128,128);
        myFrame.setVisible(true);
        System.out.println("Waiting");
        while(!flag[0]){}
        System.out.println("Finished");
    }
}

This never prints "done" and prints once after clicking the button

Waiting
Button was clicked!

But if I modify the while loop to read

while(!flag[0]){
    System.out.println("I should do nothing. I am just a print statement.");
}

This works! The printout looks like

Waiting
I should do nothing. I am just a print statement.
I should do nothing. I am just a print statement.
....
I should do nothing. I am just a print statement.
Button was clicked!
Finished

I understand that this may not be the right way to wait for an action, but I'm still interested in knowing why Java runs this way

Solution

The most likely reason is that flag [0] = true; It is executed on the UI thread, while while (! Flag [0]) is executed on the main thread

Without synchronization, there is no guarantee that changes made in the UI thread will be visible from the main thread

By adding system out. Println, you will introduce a synchronization point (because the println method is synchronized) and the problem is solved

You can set the flag to a volatile instance or class boolean variable (not an array), or more simply, put any code to be executed on the button pressed in the listener itself

For reference, the code with volatile variable is as follows:

private static volatile boolean flag;
public static void main(String[] args) {
  JFrame myFrame = new JFrame("Test");
  JButton myButton = new JButton("Click Me!");
  myButton.addActionListener(new ActionListener() {
    @Override public void actionPerformed(ActionEvent arg0) {
      System.out.println("Button was clicked!");
      flag = true;
    }
  });
  myFrame.add(myButton);
  myFrame.setSize(128,128);
  myFrame.setVisible(true);
  System.out.println("Waiting");
  while (!flag) { }
  System.out.println("Finished");
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>