所以我有一个很大的项目,但最终将问题归结为以下情况。

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

循环测试:

public class LoopTest {

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


}

RandomClassObject:

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等到按下按钮。
我有一个“创建的”布尔值,并有一个while循环,直到所说的布尔值更改为true为止。

在注释掉SOUT“ Done”的情况下运行时,我单击了按钮,但是没有得到第二个SOUT“ It was was Created”。

在未注释SOUT“完成”的情况下运行时,我会收到“完成”的垃圾邮件,单击按钮后,我将收到“已创建” SOUT。

我需要帮助来理解为什么我必须在While循环中放置一个SOUT,以使我的循环永远不会在buttonClick上退出。

抱歉,这是一个明显的错误,感谢您的答复!

最佳答案

您有一个同步问题。在事件线程中发生按钮单击,并且您的循环(在主线程中运行)从未看到它所做的更新。因为您不强制两个线程之间进行内存同步,所以计算机可以自由地忽略更改。

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()释放闩锁。

10-01 17:23
查看更多