Programmierung

Ressourcen freigeben

Bei Nr. 41 der Tüftelfragen in Java Puzzlers von Joshua Bloch und Neil Gafter (2. Auflage, 2005) geht es darum, wie zwei Datenströme, ein Eingabestrom und ein Ausgabestrom, sicher geschlossen werden, somit so, dass auf jeden Fall – also auch wenn eine Ausnahme erhoben wurde, und bei der Behandlung dieser dann eine weitere Ausnahme eintritt – beide Ströme geschlossen, und die an ihnen hängenden Ressourcen freigegeben werden. Das Problem ist keineswegs akademisch: So kann es bei einer verteilten Web-Applikation nicht einfach sein, ein Loch zu finden, das sich nur bei erhöhter Last bemerkbar macht, etwa wenn die maximale Anzahl von Dateideskriptoren verbraucht wird, weil Dateien oder Verbindungen nicht korrekt geschlossen wurden.

Wie Bloch später bemerkte, ist auch die Lösung im Buch defekt. In seinem Vorschlag eines Automatic Resource Management für Java 7 reicht er die minimale korrekte Lösung nach und entwirft die Syntax eines try-Blocks mit Ressourcendeklaration (try-with-resources), der Java-Programmierer die Last abnehmen soll, diese Lösung als Idiom anzuwenden. Die Lösung lässt noch Wünsche übrig, weil beim Auftreten von zwei oder mehr Ausnahmen nur eine weitergegeben wird. Auch bei der neuen Syntax verdrängt die letzte Ausnahme die vorigen, aber das Konstrukt garantiert immerhin, dass alle als Parameter zum try deklarierten Ressourcen freigegeben werden.

Die neue Syntax wird in Byte-Code kompiliert, welcher der entzuckerten (desugared) ausgeschriebenen Variante entspricht.

static void copy( String src, String dest )
    throws IOException {
    InputStream in = new FileInputStream(src);
    try {
        OutputStream out = new FileOutputStream(dest);
        try {
            byte[] buf = new byte[8 * 1024];
            int n;
            while ((n = in.read(buf)) >= 0)
                out.write(buf, 0, n);
        } finally {
            out.close();
        }
    } finally {
        in.close();
    }
}

Die Version mit automatischem Ressourcen-Management ist etwas kompakter.

static void copy( String src, String dest )
    throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dest)) {
    byte[] buf = new byte[8 * 1024];
    int n;
    while ((n = in.read(buf)) >= 0)
        out.write(buf, 0, n);
    }
}

(Beiläufig sei erwähnt, dass wir in Java 7 für dieses einfache Beispiel, in welchem die Bytes einer Datei in eine andere kopiert werden, auch die Methode copy des neuen Klassenpaketes java.nio.file.Files verwenden könnten.)

16. Juni 2011 von Kai Yves Linden
Kategorien: Programmierung | Schlagwörter: , | Kommentare deaktiviert für Ressourcen freigeben