Yo esperaría que la JVM con gracia interrumpe (thread.interrupt()
) todos los subprocesos que se ejecutan creados por la aplicación, al menos para las señales SIGINT (kill -2)
y SIGTERM (kill -15)
.
De esta manera, la señal se les enviará, lo que permite una cancelación de hilo elegante y la finalización de recursos en el standard ways.
Pero este no es el caso (al menos en mi aplicación JVM:.. Java(TM) SE Runtime Environment (build 1.8.0_25-b17), Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
como se ha comentado otros usuarios, el uso de ganchos de cierre parece obligatoria
Así que, ¿cómo puedo lo manejaría?
Bueno, no me importa en todos los programas, solo en aquellos en los que quiero hacer un seguimiento de cancelaciones de usuarios y fines inesperados. Por ejemplo, imagine que su programa Java es un proceso hombre envejecido por otro. Es posible que desee diferenciar si ha finalizado correctamente (SIGTERM
desde el proceso del administrador) o si se ha producido un apagado (para reiniciar automáticamente el trabajo al inicio).
Como base, siempre hago que mis hilos de ejecución prolongada sean conscientes periódicamente del estado interrumpido y lanzo un InterruptedException
si se interrumpen. Esto permite la finalización de la ejecución de una manera controlada por el desarrollador (que también produce el mismo resultado que las operaciones de bloqueo estándar). Luego, en el nivel superior de la pila de hilos, se captura InterruptedException
y se realiza una limpieza adecuada. Estos hilos están codificados para saber cómo responder a una solicitud de interrupción. Alto cohesion diseño.
Por lo tanto, en estos casos, agrego un gancho de cierre, que hace lo que yo creo que la JVM debe hacer de forma predeterminada: interrumpir todos los hilos no demonio creados por mi solicitud que todavía se están ejecutando:
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("Interrupting threads");
Set<Thread> runningThreads = Thread.getAllStackTraces().keySet();
for (Thread th : runningThreads) {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.getClass().getName().startsWith("org.brutusin")) {
System.out.println("Interrupting '" + th.getClass() + "' termination");
th.interrupt();
}
}
for (Thread th : runningThreads) {
try {
if (th != Thread.currentThread()
&& !th.isDaemon()
&& th.isInterrupted()) {
System.out.println("Waiting '" + th.getName() + "' termination");
th.join();
}
} catch (InterruptedException ex) {
System.out.println("Shutdown interrupted");
}
}
System.out.println("Shutdown finished");
}
});
Aplicación de prueba completa en github: https://github.com/idelvall/kill-test
'kill -9' significa para mí:" Begone, foul process, away withe! ", Sobre el cual el proceso dejará de ser. Inmediatamente. – ZoogieZork
En la mayoría de los * nixes de los que tengo conocimiento, kill -9 no puede ser interceptado y manejado con gracia por ningún programa, sin importar en qué idioma esté escrito. –
@Begui: además de lo que otros comentaron y respondieron, * IF * su sistema operativo Un * x no mata al instante * Y RECUPERAR TODOS LOS RECURSOS * utilizados por el programa * kill -9'ed *, bueno ... El sistema operativo está roto. – SyntaxT3rr0r