Einfügen eines ShutdownHook für Aufräumarbeiten beim Beenden

Ideen und Lösungen zu Programmierproblemen sowie nützliche Tipps für effizienteres Arbeiten mit Java

Einfügen eines ShutdownHook für Aufräumarbeiten beim Beenden

Postby kottmair » Tue Jan 14, 2014 1:13 pm

Nicht immer laufen Java-Programme unbeeinflusst vom Anfang bis zum Ende durch. In den Fällen, in denen die Java-Laufzeitumgebung beendet wird, bevor die letzte Codezeile des Programms erreicht wurde, besteht die Möglichkeit, dass bestimmte "Aufräumarbeiten" noch nicht ausgeführt wurden. Beispiele für solche Aufräumarbeiten sind das Löschen einer (temporären) Datei oder das korrekte Schließen einer geöffneten Datenbankverbindung.

Betrachten wir beispielsweise eine statische Klasse DatabaseAccess, die von anderen Klassen der Anwendung für den Zugriff auf Inhalte einer Datenbank verwendet wird:

Code: Select all
class DatabaseAccess {
  private static DatabaseAccess INSTANCE = null;

  private DatabaseAccess() {
    // Klasse soll nicht instantiiert werden können (Singleton)
  }

  public static DatabaseAccess getInstance() {
    if (INSTANCE == null) {
      connect(); // Verbindung automatisch herstellen
      INSTANCE = this;
    }
    return INSTANCE;
  }

  private void connect() {
    // Code zum Herstellen der Datenbankverbindung
  }

  private void disconnect() {
    // Code zum korrekten Trennen der Datenbankverbindung
  }
}


Die Klasse kann von allen anderen Teilen der Anwendung über die statische Funktion DatabaseAccess.getInstance() genutzt werden. Um das Herstellen und Trennen der Verbindung muss sich der Aufrufer dabei nicht kümmern. Er kann sich auch gar nicht darum kümmern, da die entsprechenden Methoden als private deklariert sind. Dies dient dazu, zu verhindern, dass die Datenbankverbindung (versehentlich) über einen Aufruf der Methode disconnect() getrennt wird, obwohl sie an anderer Stelle noch benötigt wird. Leider kümmert sich aber niemand darum, die Verbindung am Ende des Programms auch zu trennen. In großen Anwendungen ist auch nicht immer ganz klar, wann die Anwendung denn beendet wird (das kann an mehreren Stellen passieren). Um nicht an jedem denkbaren Ausstiegspunkt eine Anweisung DatabaseAccess.getInstance().disconnect() einbauen zu müssen und trotzdem sicherzustellen, dass die Verbindung am Ende stets korrekt getrennt wird, kann ein sogenannter ShutdownHook eingefügt werden:

Code: Select all
  public DatabaseAccess getInstance() {
    if (INSTANCE == null) {
      connect(); // Verbindung automatisch herstellen
      INSTANCE = this;
      Runtime.getRuntime().addShutdownHook(new Thread() {
          @Override
          public void run() {
              disconnect();
          }
      });
    }
    return INSTANCE;
  }


Ein ShutdownHook ist ein (zunächst inaktiver) Thread, der über die Methode Runtime.getRuntime().addShutdownHook() zur Ausführung beim Beenden der Laufzeitumgebung vorgemerkt wird. Beim Programmende werden alle diese Threads dann automatisch ausgeführt.

Die Methode deleteOnExit() der Klasse File setzt einen solchen ShutdownHook für die jeweilge Datei, der sie beim Beenden der Java-VM schließlich löscht.
kottmair
Site Admin
 
Posts: 8
Joined: Fri Sep 14, 2012 8:50 am

Return to Tipps und Tricks

Who is online

Users browsing this forum: No registered users and 0 guests

cron