Java 为什么我的循环只在使用SOUT时才继续?
因此,我有一个相当大的项目,但最终归结为以下情况的问题 我有主类“LoopTest”和另一个类“RandomClassObject” 循环测试: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"); }
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为止。我编辑了答案并添加了一条建议。