[英]Shutdown hook is not killing executor
I have the following code: 我有以下代码:
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...");
}
}
When this runs I get the following console output: 当运行时,我得到以下控制台输出:
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)
When I run this, the application never terminates. 当我运行此程序时,应用程序永不终止。 Instead, every 5 seconds, I see a new println of "Task is running!". 相反,每隔5秒,我会看到一个新的println“任务正在运行!”。 I would have expected the main thread to reach the end of the main
method, print "Initializing shutdown...", invoked the added shutdown hook, killed the executor, and finally print out "Shutdown hook is finished!". 我本来希望主线程到达main
方法的末尾,打印“ Initializing shutdown ...”,调用添加的shutdown钩子,杀死执行程序,最后打印出“ Shutdown钩子完成!”。
Instead, "Task is running" just keeps getting printed and the program never terminates. 相反,“任务正在运行”只会不断打印,程序永远不会终止。 What's going on here? 这里发生了什么?
I am no expert but AFAIK you must have all non-Daemon threads terminated in order for the shutdown hook to “kick in”. 我不是专家,但是AFAIK您必须终止所有非守护进程线程,才能使关闭挂接 “插入”。 In the original example you have 3 non-Daemon: 在原始示例中,您有3个非守护进程:
Timer(true)
运行“ TimerTask”的线程–由“ Timer”创建,并且您通过固定为Timer(true)
覆盖 So I think what you should do is to create a ThreadFactory and use it when initializing the “executor”. 因此,我认为您应该做的是创建一个ThreadFactory并在初始化“执行程序”时使用它。
Create a class that will be the ThreadFactory : 创建一个将是ThreadFactory的类 :
private class WorkerThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "Worker");
t.setDaemon(true);
return t;
}
}
-- the important line is the setDaemon
of course :) -当然重要的是setDaemon
:)
Pass an instance of it as a parameter to the newCachedThreadPool
method: 将其实例作为参数传递给newCachedThreadPool
方法:
private ExecutorService executor = Executors.newCachedThreadPool(new WorkerThreadFactory());
Applying these 2 changes did the trick for me and I got to: 应用这2个更改对我来说很成功,所以我做到了:
Maximum time limit of 20 reached when trying to shut down workers. Forcing shutdown.
Shutdown hook is finished!
Hope it helps, 希望能帮助到你,
Izik 伊兹克
golan2@hotmail.com golan2@hotmail.com
It is not shutting down because Timer()
creates and starts a non-daemon thread ... which is then never stopped. 它没有关闭,因为Timer()
创建并启动了一个非守护线程...然后永不停止。
There are two things that can cause the JVM to shutdown of its own accord: 有两种情况可以导致JVM自行关闭:
System.exit()
(or Runtime.halt()
) 调用System.exit()
(或Runtime.halt()
) Since you have created a second non-daemon thread (in addition to the thread that is running main()
) the second condition won't be met. 由于您创建了第二个非守护进程线程(除了运行main()
的线程之外),因此将不满足第二个条件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.