我有一个简单的,可变大小的井字游戏应用程序,在不同的机器上工作方式不同。在我的笔记本电脑上它的工作方式就像我想要的那样,在我的桌面上,它会卡在实现ButtonListener
的{{1}}类中。我很确定这是因为我正在等待使用ActionListener
循环执行操作的方式。这是违规的代码段。
while
我的意思是这个方法只是等待选择一个有效的点,并在public void playOneTurn(int player) {
waiting = true;
while (waiting) {
// Do nothing, touchEvent will change waiting.
}
}
中翻转waiting
:
ButtonListener
我对线程一无所知但是我相信 class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("TOUCHEVENT");
for (i = 0; i < size; i++)
for (j = 0; j < size; j++)
if (e.getSource() == cells[i][j]) {
if (model[i][j] == 'e') {
cells[i][j].setText("");
currentSpot[0] = i;
currentSpot[1] = j;
if (count % 2 == 0) {
cells[i][j].setBackground(Color.GREEN);
cells[i][j].setIcon(X_MARK);
model[i][j] = 'x';
count++;
waiting = false;
} else {
cells[i][j].setBackground(Color.CYAN);
cells[i][j].setIcon(O_MARK);
model[i][j] = 'o';
count++;
waiting = false;
}
} else {
System.out.println("Hey, you can't move there silly!");
}
}
}
}
正在启动一个线程,并且由于我在等待它的方式,使用ButtonListener
循环,线程永远不会停止让我的其余代码在某些机器上运行。
我在使用while循环等待一个事件来翻转一个布尔值时出错了吗?如果有的话,我将如何正确地等待它呢?
答案 0 :(得分:4)
不要简单地使用while(true)
循环。它将占用您的CPU使用率。请改用synchronization
。创建private final Object
并在其上调用wait()
。在此之前,将此对象的引用发送到MessageListener。当您在MessageListener中的操作完成后,您可以在其上调用notify()
。
还要照顾Spurious wakeups。
答案 1 :(得分:3)
您应该重新设计您的应用程序。没有必要等待。除非存在触发此类更改的某些事件(即用户输入),否则应用程序的整个状态不会更改。对于一个井字游戏来说尤其如此。除非某些用户输入以允许它的方式更改状态,否则您要等待的条件不会成立。因此,您可以在条件可能成立的位置检查侦听器内的条件。然后立即做出反应。
因此,您应该实现对事件做出反应,更改应用程序状态并返回的侦听器。下一个事件发生时将发生下一个状态转换,而不是之前的单个CPU周期。如果您想要独立于用户生成的事件(即动画)进行更改,请使用Timer
来生成相应的事件。