java:停止ESC上的线程

java:停止ESC上的线程,java,multithreading,Java,Multithreading,我正在用Java编写一个简单的游戏,我有一个问题: 我有一个名为MainGameFrame的控制类,其中初始化了gameThreadMainGameFrame有一个Esc键的键侦听器,因此它可以暂停/恢复gameThread。但是,这不起作用: public void keyPressed(KeyEvent e) { // pause the game synchronized(gameThread) { if(e.getKeyCode() == e.VK_ESC

我正在用Java编写一个简单的游戏,我有一个问题:

我有一个名为
MainGameFrame
的控制类,其中初始化了
gameThread
MainGameFrame
有一个Esc键的键侦听器,因此它可以暂停/恢复
gameThread
。但是,这不起作用:

public void keyPressed(KeyEvent e) {
    // pause the game
    synchronized(gameThread) {
        if(e.getKeyCode() == e.VK_ESCAPE) {
            try {
                if(gameThread.getState() == Thread.State.WAITING) {
                    System.out.println("continue");
                    gameThread.notify();
                    System.out.println("after continue");
                } else {
                    System.out.println("pause");
                    gameThread.wait();
                    System.out.println("after pause");
                }
            } catch (InterruptedException ex) {
                    Logger.getLogger(MainGameFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

它将在Esc上暂停并输出“暂停”,但不会输出“暂停后”。

它将等待另一个线程调用notify()。您没有这样做,因此“暂停后”永远不会打印

您希望gameThread.wait()实现什么功能?

gameThread.wait()
不会使gameThread线程暂停。它使当前线程(即事件调度线程)等待。由于EDT正在等待,它无法再接收按键事件:整个GUI冻结

阅读关于并发性的Java教程,特别是以下页面:


您可能应该更改AtomicBoolean变量的值,该变量由游戏线程定期检查,以确定是否必须暂停。然后,游戏线程将等待共享锁对象。恢复时,再次更改布尔变量并通知游戏线程。

您可以等待并向后通知

一个线程不能直接暂停或终止另一个线程。但是,您可以更改线程之间共享的变量。当感兴趣的线程看到变量已更改时,它可能会自行“暂停”

我还避免直接使用wait和notify,因为在使用wait¬ify时,您必须注意一些注意事项(例如正在等待的线程实际上必须在循环中等待,因为它可以在没有调用notify的情况下被唤醒)。

如果不使用同步块,还应确保始终按照以下模式获取和释放锁:

l.lock();
try {
  // code
} finally {
  l.unlock();
}

我还建议阅读: 在Java中进行并发编程时,陷阱比您想象的要多

不能暂停或终止来自另一个线程的线程的原因是,执行暂停或终止的线程不知道另一个线程在哪里执行,也不知道另一个线程可能拥有哪些资源


如果线程A暂停了线程B,而线程B恰好持有线程A稍后需要的多个资源,会发生什么情况?如果线程A杀死线程B,而线程B正在使用它应该对其进行特殊清理的资源,会发生什么情况?

文档中说它做了什么?我觉得你还没有把它读透。提示:当您调用
gameThread.wait()
时,当前线程是什么?正是这些bug让我希望在
线程上调用
wait()
是非法的。如果你在线程对象上调用
wait
,你几乎肯定是做错了。啊哈:)但是我如何更改它,使游戏线程停止,而不是运行MainGameFrame的线程?@Mark Peters,更不用说等待条件变量:)嗯……有一个通知,它没有被调用的原因有点微妙。不管怎样,我理解这个问题,他想知道在“暂停”被打印出来后,它不会被直接调用吗?
l.lock();
try {
  // code
} finally {
  l.unlock();
}