java:停止ESC上的线程
我正在用Java编写一个简单的游戏,我有一个问题: 我有一个名为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
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();
}