首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多个线程的java关闭钩子

具有多个线程的java关闭钩子
EN

Stack Overflow用户
提问于 2012-10-31 21:15:35
回答 3查看 3.7K关注 0票数 8

我正在尝试让一个关闭钩子在我的ubuntu服务器上工作,但是我似乎有多个线程的问题。使用基本的ShutdownHook,当我使用kill <PID>杀死进程时,以下代码可以工作,这意味着关闭行为被激活。

代码语言:javascript
复制
public static void main(String[] args) {
    ShutdownHook shutDown = new ShutdownHook();
    shutDown.attachShutDownHook();

    while(true){}
}

但是,具有附加线程的相同代码不能

代码语言:javascript
复制
public static void main(String[] args) {
    ShutdownHook shutDown = new ShutdownHook();
    shutDown.attachShutDownHook();

    (new Thread() {
        public void run() {
            while ( true ) {}
        }
    }).start();

    while(true){}
}

有什么想法吗?

代码语言:javascript
复制
class ShutdownHook {

    ShutdownHook() {
    }

    public void attachShutDownHook() {

            Runtime.getRuntime().addShutdownHook(new Thread() {
                    @Override
                    public void run() {
                            System.out.println("Shut down hook activating");
                    }
            });
            System.out.println("Shut Down Hook Attached.");

    }
}
EN

回答 3

Stack Overflow用户

发布于 2012-10-31 21:22:46

当仍有非守护进程线程在运行时,JVM不会退出。尝试在新线程上调用setDaemon(true)

票数 3
EN

Stack Overflow用户

发布于 2012-10-31 21:43:17

以我自己的一个项目为例;

我的核心类产生了一大堆工作线程,这些工作线程运行必须完成的事务。

在核心类中,我有;

代码语言:javascript
复制
Runtime.getRuntime().addShutdownHook(new ShutdownCleanup());

它看起来像这样;

代码语言:javascript
复制
public final class ShutdownCleanup extends Thread() {
    public void run() {
        log("waiting for worker threads to finish...");
        while(WorkerThread.transactionInProgress()) {
            Thread.sleep(1000);
        }
        //close various sockets and resources
    }
}

当我在终端中点击Ctrl+C时,就会出现log消息。因此shutdown钩子会立即激活,它不是在程序准备死亡时运行,而是在收到close或kill请求时立即运行。

由于这个原因,我相信其他人所说的关闭钩子永远不会被调用,而仍然有一个线程活着是错误的。关机钩子只在所有东西都死了之后才被激活,这有什么意义呢?

这可能是因为您使用的是硬删除,例如-9。您是否尝试过使用Ctrl+CSIGINT进行正常关闭

票数 1
EN

Stack Overflow用户

发布于 2012-10-31 21:21:24

java.lang.Runtime.addShutdownHook( Thread )注册一个新的虚拟机关闭钩子:

Java虚拟机在响应两种事件时关闭:

  • 当最后一个非后台进程线程退出或调用exit (相当于System.exit)方法时,程序将正常退出,或者
  • 虚拟机将终止,以响应用户中断(如键入^C )或系统范围事件(如用户注销或系统关机)。

您的代码将无限期运行,因此永远不会调用关闭钩子。

编辑完成后

您使用的是哪种kill

kill -9是不可捕获的

kill -2可用于模拟ctrl-c (SIGINT)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13158847

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档