簡體   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