Java Can';t在退出时关闭所有AWT线程
我正试图关闭我的Java应用程序,但线程却一直处于打开状态 当使用默认的windows x按钮单击close时,一切都会正常关闭(可能是因为退出\u ON\u close?)-但是当我使用编程按钮时,它会挂在thread.join()上 更糟糕的是,窗口被很好地处理了,所以用户会认为它已经关闭了——但是有几个AWT线程仍然保持打开状态。我的主线程正在等待一个id为20的线程,但我不知道如何获取线程id 有人有什么建议吗 这是我的退出代码:Java Can';t在退出时关闭所有AWT线程,java,multithreading,join,awt,exit,Java,Multithreading,Join,Awt,Exit,我正试图关闭我的Java应用程序,但线程却一直处于打开状态 当使用默认的windows x按钮单击close时,一切都会正常关闭(可能是因为退出\u ON\u close?)-但是当我使用编程按钮时,它会挂在thread.join()上 更糟糕的是,窗口被很好地处理了,所以用户会认为它已经关闭了——但是有几个AWT线程仍然保持打开状态。我的主线程正在等待一个id为20的线程,但我不知道如何获取线程id 有人有什么建议吗 这是我的退出代码: public synchronized void sto
public synchronized void stop() {
running = false;
frame.dispose();
WindowEvent wev = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
try {
if (server != null) {
server.exit();
}
client.exit();
thread.join();
new Thread(){
public void run() {
System.exit(0);
}
}.start();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
System.exit(1);
}
}
以下是退出后打开的线程:
下面是我的run()
方法的内容:
public void run() {
requestFocus();
while (running) {
getTimer().tick();
if (System.currentTimeMillis() - getTimer().getSecond() > 1000) {
// every second, add a second, print fps and mod title with fps
getTimer().accumulateSecond();
//System.out.println(getTimer().returnFPS());
frame.setTitle(title + " | " + getTimer().returnFPS());
getTimer().resetTick();
ticker++;
}
while (getTimer().getDelta() >= 1) {
// every time delta goes greater than one, update and supertick
update();
getTimer().superTick();
}
if (getTimer().getFPS() > 100) {
try {
Thread.sleep(5);
} catch (Exception e) {
System.err.println("Sleeping failed: " + e);
}
}
render();
if (ticker > 30) {
ticker = 0;
getTimer().hourTick();
}
}
stop();
}
更新: 在看到更多的代码后,我很确定您的问题在于您正在从一个线程调用
stop()
(即已同步
)。在stop()
内部,调用thread.join()
,它尝试等待thread
实例完成其run()
方法。设置running
标志会导致run()
退出其while
循环,但方法中的最后一行代码是对stop()
的另一个调用。如果这是您向我们展示的相同的stop()
方法,则会出现死锁
您的run()
方法中的stop()
调用将永远无法进入该方法,因为第一个线程仍然在stop()
中,并且正在等待run()
完成(它永远不会,因为它正在等待能够调用并进入stop()
)。僵局
您必须从run()
中删除对stop()
的调用,或者找到其他方法重新编写代码
我不会担心识别特定的线程ID。担心让所有线程正常完成 首先,
Thread#join()
不会停止线程。它等待它完成。您正在执行的其他操作必须导致/允许线程
实例完成其run()
方法
我所看到的唯一可能做到这一点的是设置
running = false;
您的线程
对象是否在其run()
方法中检查该标志?例如:
public void run() {
while (isRunning()) {
// do some work
Thread.sleep(delay);
}
}
其中isRunning()
会返回running
变量的值吗
现在,我不能不看更多的代码。但是,您可能已经选择像这样实现isRunning()
:
public synchronized boolean isRunning() {
return running;
}
如果你那样做了,那就有问题了。主线程将在您向我们展示的stop()
方法中获取锁。然后它将进入thread.join()
调用,此时它开始等待工作线程。如果工作线程随后调用在同一个锁上同步的isRunning()
,则isRunning()
将被阻止,因为主线程位于stop()
内,锁已被保持
如果线程
对象试图从您向我们展示其代码的类调用任何其他同步
方法,则可能会出现相同的基本问题
长话短说,我们需要看到更多的代码(由thread
变量表示的线程中运行的是什么)。但是,你可能已经陷入了僵局
移动
系统。退出(0)
上面的临时线程join()
可以完全关闭它,但我怀疑它是线程安全的?这里缺少的原因是什么,可能是错误的,您在内部线程类中显示的run()
方法是否与上面的stop()
方法在同一个类中?run()
中是否有调用synchronized
方法的其他调用?run()
方法直接检查running
,是的,整个过程都在它内部进行。我相信它正在等待某个子线程关闭,但我无法识别任何子线程。有关的同步方法不多,可能无法同步的资源也不多。除非您向我们展示该代码(在传递给线程对象的run()方法中运行的代码),否则我们无法帮助您。除了我已经做出的猜测之外,您所展示的还不足以调试问题。@gossfunkel,如果这与从run()
调用的stop()
方法相同,那么这就是您的问题stop()
是同步的,所以thread
将无法进入stop()
,因为另一个线程已经在stop()
中,在thread.join()
等待。亲爱的耶稣,你说得对。那太愚蠢了,非常抱歉!不幸的是,问题还没有解决。等等,我不明白。对stop()
的调用是否相同?如果是这样,那就是个问题。如果您仍然没有看到线程死亡,那么您还有另一个问题。但是,因为我们看不到其他方法的定义,所以很难说还有什么是错误的。