首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关机钩不是杀死执行者

关机钩不是杀死执行者
EN

Stack Overflow用户
提问于 2013-07-05 02:29:51
回答 2查看 1.9K关注 0票数 0

我有以下代码:

代码语言:javascript
复制
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...");
    }
}

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

代码语言:javascript
复制
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方法的末尾,打印“初始化关闭.”,调用添加的关闭钩子,杀死执行器,最后打印出“关闭钩子完成了!”。

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

EN

回答 2

Stack Overflow用户

发布于 2013-07-07 21:26:06

我不是专家,但AFAIK您必须终止所有非守护进程线程,以便关机钩子“启动”。在最初的示例中,有3个非守护进程:

  1. “Main”的线程-这是你唯一想要的非守护进程。
  2. 运行“TimerTask”的线程--它是由“Timer”创建的,您可以通过修复到Timer(true)来覆盖它。
  3. 运行“worker”的线程--它是由“executor”创建的,为了使“executor”创建守护进程线程,您应该创建一个ThreadFactory.。(至少这是我所知道的方式,也许还有其他的方法.)

因此,我认为您应该创建一个ThreadFactory,并在初始化“executor”时使用它。

创建一个类,它将是ThreadFactory

代码语言:javascript
复制
private class WorkerThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r, "Worker");
        t.setDaemon(true);
        return t;
    }
}

-当然,重要的是setDaemon :)

将它的一个实例作为参数传递给newCachedThreadPool方法:

代码语言:javascript
复制
private ExecutorService executor = Executors.newCachedThreadPool(new WorkerThreadFactory());

应用这两个变化对我来说很有意义,我不得不:

代码语言:javascript
复制
Maximum time limit of 20 reached when trying to shut down workers. Forcing shutdown.
Shutdown hook is finished!

希望能帮上忙

伊齐克

golan2@hotmail.com

票数 2
EN

Stack Overflow用户

发布于 2013-07-05 02:46:20

它不是关闭,因为Timer()创建并启动了一个非守护进程线程.然后就再也不会停止了。

有两件事可以导致JVM自行关闭:

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

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

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

https://stackoverflow.com/questions/17480280

复制
相关文章

相似问题

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