Java Shutdown挂钩未运行

我是Java / threads的新手,我inheritance了类似下面的代码。 它是一个命令行程序,main()只启动5-6种不同类型的线程,并以^ C退出。 我想添加一个关闭钩子来正确关闭所有线程并按以下方式调整它。

我在所有线程中添加了一个Shutdown钩子和一个stopThread()方法(比如MyWorker类中的那个)

问题是,当我按^ CI时,看不到Thread的run方法中的结束消息。 这是在后台完成还是我的方法有问题。 另外,我应该遵循更好的模式吗?

谢谢

public class Main { public static MyWorker worker1 = new MyWorker(); // .. various other threads here public static void startThreads() { worker1.start(); // .. start other threads } public static void stopThreads() { worker1.stopThread(); // .. stop other threads } public static void main(String[] args) throws Exception { startThreads(); // TODO this needs more work (later) Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { stopThreads(); } catch (Exception exp) { } } }); } } public class MyWorker extends Thread { private volatile boolean stop = false; public void stopThread() { stop = true; } public void run() { while (!stop) { // Do stuff here } // Print exit message with logger } } 

当您调用System.exit()或通过信号终止时,它会停止所有现有线程并启动所有关闭挂钩。 也就是说,当你挂钩开始时,你所有的线程都可能已经死了。

您应该确保资源完全关闭,而不是试图干净地停止线程。

在某些情况下可能无法执行关机挂钩!

首先要记住的是,无法保证关闭挂钩始终会运行。 如果JVM由于某些内部错误而崩溃,那么它可能会在没有机会执行单个指令的情况下崩溃。 此外,如果O / S给出SIGKILL( http://en.wikipedia.org/wiki/SIGKILL )信号(Unix / Linux中的kill -9)或TerminateProcess(Windows),则应用程序需要立即终止甚至等待任何清理活动。 除了上述内容之外,还可以通过调用Runime.halt()方法来终止JVM而不允许关闭挂钩运行。

当应用程序正常终止时(当所有线程完成或调用System.exit(0)时),将调用关闭挂钩。 此外,当JVM由于外部原因(例如用户请求终止(Ctrl + C)),由O / S(正常kill命令,不带-9)或操作系统关闭时发出SIGTERM而关闭时。

我想你可以将你的代码转移到ExectuterService

 private final ExecutorService pool; pool = Executors.newFixedThreadPool(poolSize); pool.execute(Instance of Runnable); pool.shutdown(); 

ExectuterService.shutdown

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务。 如果已经关闭,调用没有其他影响。

尝试将您的线程作为守护程序线程。

添加构造函数

 public MyWorker(boolean isDaemon) { this.setDaemon(true); } 

或者在调用start之前设置为守护进程。

 worker1.setDaemon(true); worker1.start(); 

按Ctrl C并退出时,线程将停止。

这里发生的是你调用stopThread()方法,但你不等待线程在终止之前实际完成。

如果在停止JVM之前在所有线程上调用join() ,您可能会看到“ 停止日志 ”。

 public static void stopThreads() { worker1.stopThread(); // .. stop other threads for(Thread t: workers) { t.join(); } }