Thomas Darimont
Erfahrenes Mitglied
Hallo,
schaut mal hier:
Beispielausgabe:
Gruß Tom
schaut mal hier:
Java:
package de.tutorials.training;
import java.util.concurrent.ThreadLocalRandom;
public class TryWithResourceExample {
public static void main(String[] args) {
/*
* so nicht:
* Wenn hier bei der Erzeugung einer Resource ein Fehler passiert und eine
* Exception geworfen wird, so ist nicht garantiert, dass der try-with Resource
* Mechanismus die close() Methode der bis dahin im try-with-Block erzeugten Objekte aufruft.
*/
try (Resource outer = new Resource("outer", new Resource("middle", new Resource("inner")))) {
System.out.println(outer);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
System.out.println("####");
/*
* besser so:
* Bei dieser Formulierung ist sichergestellt, dass der try-with Resource
* Mechanismus die bis dahin erstellten im try-with-Block erzeugtenObjekte
* aufruft.
*/
try (Resource outer = new Resource("outer");
Resource middle = new Resource("middle", outer);
Resource inner = new Resource("inner" , middle)) {
System.out.println(inner);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
static class Resource implements AutoCloseable {
private String id;
private Resource nested;
private volatile boolean closed;
public Resource(String id) {
this.id = id;
//mit einer Wahrscheinlichkeit von 15 % Fehler simulieren
if (ThreadLocalRandom.current().nextDouble() < 0.15) {
throw new RuntimeException("Could not create: " + id);
}
}
public Resource(String name, Resource nested) {
this(name);
this.nested = nested;
}
@Override
public void close() throws Exception {
/*
* Die close() Methode von "inneren" (nested) Resourcen aufzurufen ist
* in der Regel eine gute Idee - dies führt jedoch bei der Verwendung mit
* dem try-with Resource Mechanismus u.U. zu multiplen Aufrufen der close-Methode.
*
* Je nach Logik in close() kann das dann auch zu Problemen führen -> hier kann es sich
* anbieten ein closed-Flag einzuführen um dann in solchen Fällen nach einem check des Flags
* direkt wieder aus der Methode zurückzukehren.
*
*/
if(this.closed){
return;
}
if(this.nested != null){
this.nested.close();
//eine Thread-sichere Implementierung zu diesem Idiom findet man übrigens bei:
//java.io.BufferedInputStream.close()
}
System.out.println("Close " + this.id);
this.closed = true;
}
}
}
Beispielausgabe:
Code:
Could not create: inner
####
Close outer
Close middle
Could not create: inner
Gruß Tom