如何正确等待ActionListener执行?

时间:2014-02-19 08:32:26

标签: java multithreading swing awt actionlistener

我有一个简单的,可变大小的井字游戏应用程序,在不同的机器上工作方式不同。在我的笔记本电脑上它的工作方式就像我想要的那样,在我的桌面上,它会卡在实现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循环等待一个事件来翻转一个布尔值时出错了吗?如果有的话,我将如何正确地等待它呢?

2 个答案:

答案 0 :(得分:4)

不要简单地使用while(true)循环。它将占用您的CPU使用率。请改用synchronization。创建private final Object并在其上调用wait()。在此之前,将此对象的引用发送到MessageListener。当您在MessageListener中的操作完成后,您可以在其上调用notify()

还要照顾Spurious wakeups

答案 1 :(得分:3)

您应该重新设计您的应用程序。没有必要等待。除非存在触发此类更改的某些事件(即用户输入),否则应用程序的整个状态不会更改。对于一个井字游戏来说尤其如此。除非某些用户输入以允许它的方式更改状态,否则您要等待的条件不会成立。因此,您可以在条件可能成立的位置检查侦听器内的条件。然后立即做出反应。

因此,您应该实现对事件做出反应,更改应用程序状态并返回的侦听器。下一个事件发生时将发生下一个状态转换,而不是之前的单个CPU周期。如果您想要独立于用户生成的事件(即动画)进行更改,请使用Timer来生成相应的事件。