繁体   English   中英

关机挂钩不会杀死执行程序

[英]Shutdown hook is not killing executor

我有以下代码:

public class Driver {
    private ExecutorService executor = Executors.newCachedThreadPool();

    public static void main(String[] args) {
        Driver d = new Driver();
        d.run();
    }

    private void run() {
        final Timer timer = new Timer();
        final TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Task is running!");
            }
        };

        Runnable worker = new Runnable() {
            @Override
            public void run() {
                timer.scheduleAtFixedRate(task, new Date(), 5 * 1000);
            }
        };

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                System.out.println("Shutdown hook is being invoked!");

                try {
                    if(executor.awaitTermination(20, TimeUnit.SECONDS))
                        System.out.println("All workers shutdown properly.");
                    else {
                        System.out.println(String.format("Maximum time limit of %s reached " +
                                "when trying to shut down workers. Forcing shutdown.", 20));
                        executor.shutdownNow();
                    }
                } catch (InterruptedException interrupt) {
                    System.out.println("Shutdown hook interrupted by exception: " +
                            interrupt.getMessage());
                }

                System.out.println("Shutdown hook is finished!");
            }
        });

        executor.submit(worker);

        System.out.println("Initializing shutdown...");
    }
}

当运行时,我得到以下控制台输出:

Initializing shutdown...
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
Task is running!
... (this keeps going non-stop)

当我运行此程序时,应用程序永不终止。 相反,每隔5秒,我会看到一个新的println“任务正在运行!”。 我本来希望主线程到达main方法的末尾,打印“ Initializing shutdown ...”,调用添加的shutdown钩子,杀死执行程序,最后打印出“ Shutdown钩子完成!”。

相反,“任务正在运行”只会不断打印,程序永远不会终止。 这里发生了什么?

我不是专家,但是AFAIK您必须终止所有非守护进程线程,才能使关闭挂接 “插入”。 在原始示例中,您有3个非守护进程:

  1. “ Main”线程–这是您想要的唯一非守护程序。
  2. 运行“ TimerTask”的线程–由“ Timer”创建,并且您通过固定为Timer(true)覆盖
  3. 运行“工作者”的线程–它是由“执行者”创建的,并且为了使“执行者”创建守护程序线程,您应该创建一个ThreadFactory (至少这是我所知道的方式;可能还有其他方式...)

因此,我认为您应该做的是创建一个ThreadFactory并在初始化“执行程序”时使用它。

创建一个将是ThreadFactory的类

private class WorkerThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, "Worker");
        t.setDaemon(true);
        return t;
    }
}

-当然重要的是setDaemon :)

将其实例作为参数传递给newCachedThreadPool方法:

private ExecutorService executor = Executors.newCachedThreadPool(new WorkerThreadFactory());

应用这2个更改对我来说很成功,所以我做到了:

Maximum time limit of 20 reached when trying to shut down workers. Forcing shutdown.
Shutdown hook is finished!

希望能帮助到你,
伊兹克

golan2@hotmail.com

它没有关闭,因为Timer()创建并启动了一个非守护线程...然后永不停止。

有两种情况可以导致JVM自行关闭:

  • 调用System.exit() (或Runtime.halt()
  • 最后剩余的非守护线程的终止。

由于您创建了第二个非守护进程线程(除了运行main()的线程之外),因此将不满足第二个条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM