Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我的循环只在使用SOUT时才继续?_Java_Netbeans - Fatal编程技术网

Java 为什么我的循环只在使用SOUT时才继续?

Java 为什么我的循环只在使用SOUT时才继续?,java,netbeans,Java,Netbeans,因此,我有一个相当大的项目,但最终归结为以下情况的问题 我有主类“LoopTest”和另一个类“RandomClassObject” 循环测试: public class LoopTest { static RandomClassObject rco; public static void main(String[] args) { rco = new RandomClassObject(); System.out.println("RCO has finished"); }

因此,我有一个相当大的项目,但最终归结为以下情况的问题

我有主类“LoopTest”和另一个类“RandomClassObject”

循环测试:

public class LoopTest {

static RandomClassObject rco;
public static void main(String[] args) {
    rco = new RandomClassObject();
    System.out.println("RCO has finished");
}
public class RandomClassObject {

JFrame frame = new JFrame();
JButton button = new JButton("Click Me");
boolean created = false;

public RandomClassObject() {
    button.addActionListener(this::buttonActionPerformed);
    frame.add(button);
    frame.setVisible(true);
    while (!created) {
        //System.out.println("Done"); //This needs to be uncommented to work.
    }
    System.out.println("It was been Created");
}

public void buttonActionPerformed(ActionEvent evt) {
    created = true;
}
}

随机类对象:

public class LoopTest {

static RandomClassObject rco;
public static void main(String[] args) {
    rco = new RandomClassObject();
    System.out.println("RCO has finished");
}
public class RandomClassObject {

JFrame frame = new JFrame();
JButton button = new JButton("Click Me");
boolean created = false;

public RandomClassObject() {
    button.addActionListener(this::buttonActionPerformed);
    frame.add(button);
    frame.setVisible(true);
    while (!created) {
        //System.out.println("Done"); //This needs to be uncommented to work.
    }
    System.out.println("It was been Created");
}

public void buttonActionPerformed(ActionEvent evt) {
    created = true;
}
因此,我希望我的RandomClassObject等待按钮按下。 我有一个布尔值“created”,还有一个while循环,循环直到所说的布尔值变为true

当运行时,SOUT“Done”被注释掉,我单击按钮,但从未得到第二个SOUT“It has Created”

当运行未注释的SOUT“Done”时,我会收到“Done”的垃圾邮件,一旦我点击按钮,我就会收到SOUT“它已创建”

我需要帮助理解为什么我必须在While循环中放置一个SOUT,这样我的循环才能在按钮点击时退出


抱歉,如果这是一个明显的错误,感谢您的回复

您有一个同步问题。按钮点击发生在事件线程中,而您的循环(在主线程中运行)永远看不到它所做的更新。因为您不强制两个线程之间的内存同步,所以机器可以随意忽略更改

调用
System.out.println
的副作用是强制内存同步,允许主线程查看事件线程所做的更改

要解决此问题,请将
created
设置为
AtomicBoolean
或将
synchronized
关键字添加到
complete
方法中

在任何情况下,循环都不是实现此结果的好方法。考虑从按钮上的事件侦听器驱动完成逻辑。

你说你需要暂停你的主线程,直到角色被创建。一种方法是使用闩锁:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);

        JFrame frame = new JFrame("Test...");
        JButton button = new JButton("Click Me");
        button.addActionListener(e -> latch.countDown());
        frame.add(button);
        frame.pack();
        frame.setVisible(true);

        // Wait here for the click in the event thread
        latch.await();

        System.out.println("Clicked!");

        frame.dispose();
    }
}

调用
latch.await()
将阻止主线程,直到事件线程使用
latch.countDown()
释放闩锁为止。如果您有同步问题。按钮点击发生在事件线程中,而您的循环(在主线程中运行)永远看不到它所做的更新。因为您不强制两个线程之间的内存同步,所以机器可以随意忽略更改

调用
System.out.println
的副作用是强制内存同步,允许主线程查看事件线程所做的更改

要解决此问题,请将
created
设置为
AtomicBoolean
或将
synchronized
关键字添加到
complete
方法中

在任何情况下,循环都不是实现此结果的好方法。考虑从按钮上的事件侦听器驱动完成逻辑。

你说你需要暂停你的主线程,直到角色被创建。一种方法是使用闩锁:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);

        JFrame frame = new JFrame("Test...");
        JButton button = new JButton("Click Me");
        button.addActionListener(e -> latch.countDown());
        frame.add(button);
        frame.pack();
        frame.setVisible(true);

        // Wait here for the click in the event thread
        latch.await();

        System.out.println("Clicked!");

        frame.dispose();
    }
}

调用
latch.await()
将阻止主线程,直到事件线程使用
latch.countDown()

谢谢@teppic!我的完整方法之前的synchronized关键字有帮助。我明白了,你说对按钮使用事件监听器会更好,但是我需要这个循环来暂停主程序,直到单击对象RCO为止。我已经编辑了答案并添加了一条建议。谢谢@teppic!我的完整方法之前的synchronized关键字有帮助。我明白了,你说对按钮使用事件监听器会更好,但是我需要这个循环来暂停主程序,直到单击对象RCO为止。我编辑了答案并添加了一条建议。