2011-05-17 24 views
11

Digamos, por ejemplo, que tengo mi aplicación ejecutándose en un terminal Linux y presiono "CTRL + C" en mi teclado para matar el proceso que terminará el programa Java.¿Cómo implemento la terminación elegante en Java?

¿Hay alguna forma de detectar esta "solicitud" en mi aplicación Java para poder cerrarla correctamente y liberar todos los recursos/registros de escritura? Tengo varios subprocesos en ejecución si hace una diferencia en la respuesta.

Sé que tiene un addShutDownHook, pero como está escrito en la documentación de Java, no se llama bajo ciertas circunstancias, como la señal de muerte de "CTRL + C" en Linux ... ¿hay alguna otra manera?

Runtime.getRuntime().addShutdownHook(new Thread() 
{ 
    public void run() 
    { 
     // TODO: implement graceful shutdown here. 
    } 
}); 

Respuesta

3

creo que el descargo de responsabilidad es allí sólo por kill -9, de modo que no se basan en el gancho de cierre que se invoca para mantener decir la consistencia de los datos.

Entonces, si el SO permite que el proceso actúe sobre la señal, se invoca el cierre, lo cual es bastante obvio si conoce cómo funciona un sistema operativo, pero quizás no a todos los desarrolladores de Java.

En realidad se explica en gran detalle en el javadoc.

También vale la pena tener en cuenta que puede haber varios ganchos de apagado registrados en una máquina virtual, por lo que es posible que el suyo no sea EL gancho de cierre, solo uno de varios.

+0

ganchos de apagado tampoco serán llamados si se detiene la JVM http://download.oracle.com/javase/6/ docs/api/java/lang/Runtime.html # halt (int) –

+1

@Nathan D. Ryan Cierto, es bastante razonable, creo. :) En resumen, no se invocarán en situaciones en las que no haya nada que puedas hacer de todos modos. – biziclop

2

Esto funciona para mí, la captura de SIGINT/Ctrl-C en Linux:

public class TestShutdownHook 
{ 
    public static void main(final String[] args) throws InterruptedException 
    { 
     Runtime.getRuntime().addShutdownHook(new Thread() 
     { 
      @Override 
      public void run() 
      { 
       System.out.println("Shutdown hook ran!"); 
      } 
     }); 

     while (true) 
     { 
      Thread.sleep(1000); 
     } 
    } 
} 
Cuestiones relacionadas