为什么不ShutdownHook
向您的应用程序添加一个?
关闭挂钩只是一个已初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩并让它们同时运行。当所有钩子都完成后,如果 finalization-on-exit 已启用,它将运行所有未调用的终结器。最后,虚拟机将停止。请注意,在关闭序列期间,守护线程将继续运行,如果通过调用 exit 方法启动关闭,非守护线程也将继续运行。
这将允许您的 jar 在关闭之前正常终止:
public class ShutdownHookDemo {
public void start() {
System.out.println("Demo");
ShutdownHook shutdownHook = new ShutdownHook();
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
public static void main(String[] args) {
ShutdownHookDemo demo = new ShutdownHookDemo();
demo.start();
try {
System.in.read();
}
catch(Exception e) {
}
}
}
class ShutdownHook extends Thread {
public void run() {
System.out.println("Shutting down");
//terminate all other stuff for the application before it exits
}
}
重要的是要注意
关闭挂钩在以下情况下运行:
- 程序正常存在。例如,调用 System.exit(),或者最后一个非守护线程退出。
- 虚拟机被终止。例如 CTRL-C。这对应于 kill -SIGTERM pid 或
- 在 Unix 系统上杀死 -15 pid。
在以下情况下,关闭挂钩将不会运行:
- 虚拟机中止
- SIGKILL 信号被发送到 Unix 系统上的虚拟机进程。例如 kill -SIGKILL pid 或 kill -9 pid
- TerminateProcess 调用被发送到 Windows 系统上的进程。
或者,如果您必须使用它来调用类中的方法:
public class ReflectionDemo {
public void print(String str, int value) {
System.out.println(str);
System.out.println(value);
}
public static int getNumber() { return 42; }
public static void main(String[] args) throws Exception {
Class<?> clazz = ReflectionDemo.class;//class name goes here
// static call
Method getNumber = clazz.getMethod("getNumber");
int i = (Integer) getNumber.invoke(null /* static */);
// instance call
Constructor<?> ctor = clazz.getConstructor();
Object instance = ctor.newInstance();
Method print = clazz.getMethod("print", String.class, Integer.TYPE);
print.invoke(instance, "Hello, World!", i);
}
}
并动态加载一个类:
ClassLoader loader = URLClassLoader.newInstance(
new URL[] { yourURL },
getClass().getClassLoader()
);
Class<?> clazz = Class.forName("mypackage.MyClass", true, loader);
Class<? extends Runnable> runClass = clazz.asSubclass(Runnable.class);
参考: