Gancho de apagado de JVM en Java

Shutdown Hooks es una construcción especial que permite a los desarrolladores conectar un fragmento de código para que se ejecute cuando la JVM se está cerrando. Esto es útil en los casos en que necesitamos realizar operaciones especiales de limpieza en caso de que la máquina virtual se apague.
Manejar esto usando las construcciones generales, como asegurarnos de que llamamos a un procedimiento especial antes de que la aplicación salga (llamar a System.exit(0) ) no funcionará en situaciones en las que la VM se apague debido a una razón externa (p. ej., solicitud de eliminación del sistema operativo), o debido a un problema de recursos (memoria insuficiente). Como veremos pronto, los ganchos de apagado resuelven este problema fácilmente, permitiéndonos proporcionar un bloque de código arbitrario, que será llamado por la JVM cuando se esté apagando.
Desde la superficie, usar un gancho de apagado es francamente sencillo. Todo lo que tenemos que hacer es simplemente escribir una clase que amplíe la clase java.lang.Thread y proporcionar la lógica que queremos ejecutar cuando la VM se esté apagando, dentro del método public void run(). Luego registramos una instancia de esta clase como un enlace de apagado a la máquina virtual llamando al método Runtime.getRuntime().addShutdownHook(Thread). Si necesita eliminar un enlace de apagado previamente registrado, la clase Runtime también proporciona el método removeShutdownHook(Thread).
Ejemplo 1 (clase interna anónima): 
 

Java

public class ShutDownHook
{
  public static void main(String[] args)
  {
 
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
      public void run()
      {
        System.out.println("Shutdown Hook is running !");
      }
    });
    System.out.println("Application Terminating ...");
  }
}

Cuando ejecutemos el código anterior, verá que la JVM llama al enlace de apagado cuando finaliza la ejecución del método principal.
Producción: 
 

Application Terminating ...
Shutdown Hook is running !

Ejemplo 2
 

Java

class ThreadChild extends Thread {
     
    public void run() {
         
        System.out.println("In clean up code");
        System.out.println("In shutdown hook");
    }
}
 
class Demo {
     
    public static void main(String[] args) {
         
        Runtime current = Runtime.getRuntime();
        current.addShutdownHook(new ThreadChild());
 
        for(int i = 1; i <= 10; i++)
            System.out.println("2 X " + i + " = " + 2 * i);
    }
}

Producción: 
 

2 X 1 = 2
2 X 2 = 4
2 X 3 = 6
2 X 4 = 8
2 X 5 = 10
2 X 6 = 12
2 X 7 = 14
2 X 8 = 16
2 X 9 = 18
2 X 10 = 20
In clean up code
In shutdown hook

¿Simple verdad? Sí, lo es.
Si bien es bastante simple escribir un gancho de apagado, uno necesita conocer las partes internas detrás de los ganchos de apagado para usarlos correctamente. Por lo tanto, en este artículo, exploraremos algunos de los «errores» detrás del diseño del gancho de apagado.
1. ¡Los ganchos de apagado pueden no ejecutarse en algunos casos! 
Lo primero que debe tener en cuenta es que no se garantiza que los ganchos de apagado se ejecuten siempre. Si la JVM se bloquea debido a algún error interno, es posible que se bloquee sin tener la oportunidad de ejecutar una sola instrucción. Además, si el sistema operativo da una señal SIGKILL (http://en.wikipedia.org/wiki/SIGKILL) (kill -9 en Unix/Linux) o TerminateProcess (Windows), entonces se requiere que la aplicación finalice inmediatamente sin haciendo incluso esperando cualquier actividad de limpieza. Además de lo anterior, también es posible finalizar la JVM sin permitir que se ejecuten los ganchos de apagado llamando al método Runtime.halt().
Los ganchos de apagado se llaman cuando la aplicación finaliza normalmente (cuando todos los subprocesos finalizan o cuando se llama a System.exit(0)). Además, cuando la JVM se está cerrando debido a causas externas, como un usuario que solicita una terminación (Ctrl+C), un SIGTERM emitido por O/S (comando de eliminación normal, sin -9), o cuando el sistema operativo se está cerrando abajo.
2. Una vez iniciados, los Shutdown Hooks pueden detenerse por la fuerza antes de completarse. 
Este es en realidad un caso especial del caso explicado antes. Aunque el enlace comienza a ejecutarse, es posible que se termine antes de que se complete, en casos como los cierres del sistema operativo. En este tipo de caso, el O/S espera a que finalice un proceso durante un período de tiempo específico una vez que se proporciona el SIGTERM. Si el proceso no finaliza dentro de este límite de tiempo, el O/S finaliza el proceso por la fuerza emitiendo un SIGTERM (o las contrapartes en Windows). Entonces, es posible que esto suceda cuando el enlace de apagado está a la mitad de su ejecución.
Por lo tanto, se recomienda asegurarse de que los Shutdown Hooks se escriban con cautela, asegurándose de que finalicen rápidamente y no provoquen situaciones como interbloqueos. Además, el JavaDoc [1] menciona específicamente que no se deben realizar cálculos largos ni esperar operaciones de E/S del usuario en un enlace de apagado.
3. Podemos tener más de un Shutdown Hooks, pero no se garantiza su orden de ejecución.  
Como habrá adivinado correctamente por el nombre del método addShutdownHook (en lugar de setShutdownHook), puede registrar más de un enlace de apagado. Pero el orden de ejecución de estos ganchos múltiples no está garantizado por la JVM. La JVM puede ejecutar ganchos de apagado en cualquier orden arbitrario. Además, la JVM podría ejecutar todos estos ganchos al mismo tiempo.
4. No podemos registrar o anular el registro de Shutdown Hooks dentro de Shutdown Hooks 
Una vez que la JVM inicia la secuencia de apagado, no se permite agregar más ni eliminar ningún Shutdown Hooks existente. Si se intenta esto, la JVM lanza IllegalStateException.
5. Una vez que comienza la secuencia de apagado, solo Runtime.halt() puede detenerla.  
Una vez que comienza la secuencia de apagado, solo Runtime.halt() (que finaliza a la fuerza la JVM) puede detener la ejecución de la secuencia de apagado (excepto por influencias externas como SIGKILL). Esto significa que llamar a System.exit() dentro de un Shutdown Hook no funcionará. En realidad, si llama a System.exit() dentro de un Shutdown Hook, la máquina virtual puede atascarse y es posible que tengamos que terminar el proceso a la fuerza.
6. El uso de ganchos de apagado requiere permisos de seguridad. 
Si usamos Java Security Managers, entonces el código que realiza la adición/eliminación de ganchos de apagado debe tener el permiso de ganchos de apagado en tiempo de ejecución. Si invocamos este método sin permiso en un entorno seguro, resultará en SecurityException.
Referencias: 
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) Saket Kumar
contribuye con este artículo . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *