Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Can';t在退出时关闭所有AWT线程_Java_Multithreading_Join_Awt_Exit - Fatal编程技术网

Java Can';t在退出时关闭所有AWT线程

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

我正试图关闭我的Java应用程序,但线程却一直处于打开状态

当使用默认的windows x按钮单击close时,一切都会正常关闭(可能是因为退出\u ON\u close?)-但是当我使用编程按钮时,它会挂在thread.join()上

更糟糕的是,窗口被很好地处理了,所以用户会认为它已经关闭了——但是有几个AWT线程仍然保持打开状态。我的主线程正在等待一个id为20的线程,但我不知道如何获取线程id

有人有什么建议吗

这是我的退出代码:

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()
的调用是否相同?如果是这样,那就是个问题。如果您仍然没有看到线程死亡,那么您还有另一个问题。但是,因为我们看不到其他方法的定义,所以很难说还有什么是错误的。