所以我有一个很大的项目,但最终将问题归结为以下情况。
我有主类“ 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()
释放闩锁。