Mit dem JDK 1.3 hat Sun Microsystems endlich eine Threadsichere Version geschaffen, um den "Destruktor" - die finalize () Methode zwingend durch Ihre Anwendung auszuführen. Das kleine "Micro-Framework" zeigt Ihnen, wie Sie mit Hilfe eines einfachen Interfaces und einer Klasse vom Typ Runable dieses Prinzip nutzen können, um auch beim Beenden Ihrer Anwendung einen konsistenten Stand zu erreichen,
Das folgende Interface lassen Sie von allen Klassen implementieren, die bei der Beendigung Ihrer Anwendung unbedingt noch "Aufräumarbeiten" erledigen müssen.
packagede.bastie.howto.lang.java;/** * Title: Make Java - How To * Description: Ausführen der finalize() Methode erzwingen * Copyright: Copyright © 2002 - free for all use * @author Bastie - Sebastian Ritter * @version 1.0.0.0 * Dieses Interface hat lediglich den Zweck für die Methode finalize eine * erweiterte Sichtbarkeit / Erreichbarkeit zu erreichen. * Alle Typen die zwingend ordnungsgemäß beendet werden müssen, müssen dieses * Interface implementieren. */public interfaceNeedToFinalize{/** Die Methode finalize wird mit einer Sichtbarkeit public * ausgestattet. */public voidfinalize (); }
Die nächste Klasse ShutdownHook übernimmt die Verwaltung und wird beim
Typ Runtime registriert. Ausgeführt wird der registrierte
Thread, sobald die JVM mit ihrem Shutdown beginnt.
packagede.bastie.howto.lang.java;importjava.util.HashSet;importjava.util.Iterator;/** Diese Klasse realisiert den ShutdownHook, welcher für ein ordnungsgemäßes * Herunterfahren der Anwendung zuständig ist. Sie muss, um die Funktionalität * auszuführen das Interface Runnable implementieren. * @pattern Singleton */public classShutdownHookimplementsRunnable{private staticShutdownHook hook;privateShutdownHook (){};/** Ein HashSet Objekt wurde hier gewählt, um die Aufnahme doppelter * Elemente zu vermeiden. Sie können auch eine andere Speicherstruktur wählen, * um die Objekte zu sichern. */private staticHashSet objects =newHashSet ();/** Fügt ein Objekt, welches zwingend ordentlich abgeschlossen werden muss * hinzu. * @param NeetToFinalize object */public static voidaddNeedToFinalize (finalNeedToFinalize needToFinalize){//Singleton Instanz vorhanden?if(hook ==null) { ShutdownHook.hook =newShutdownHook ();//Unseren ShutdownHook hinzufügenRuntime.getRuntime ().addShutdownHook (newThread (ShutdownHook.hook)); }//Das übergebende Objekt merkenShutdownHook.objects.add (needToFinalize); }/** Entfernt ein Objekt wieder. Diese Methode sollte aufgerufen werden, bevor * das Objekt während des Programmablaufes entfernt wird (z.B. = null), * um den Speicher nicht unnötig zu belasten. * @param NeedToFinalize object */public static voidremoveNeedToFinalize (finalNeedToFinalize needToFinalize){ ShutdownHook.objects.remove (needToFinalize); }/** Die hier aufgeführten Aufgaben werden ausgeführt, wenn die JVM Ihren * Shutdown Prozess beginnt. * @pattern MethodDelegate */public voidrun (){this.finalizeObjects (); }/** Hier rufen wir die finalize Operation für unsere Objekte auf. */private voidfinalizeObjects () {//Besorgen eines IterationsobjektesfinalIterator iterator = ShutdownHook.objects.iterator ();//Für alle Iteratorobjekte die finalize Operation aufrufen.while(iterator.hasNext()){ ((NeedToFinalize) iterator.next ()).finalize (); } } }
Sofern Sie dies jetzt testen wollen, können Sie zum Beispiel auf die folgende Klasse zurückgreifen.
all rights reserved © Bastie - Sebastian Ritter @: w³: http://www.Bastie.depackagede.bastie.howto.lang.java;/** * Title: Make Java - How To * Description: Ausführen der finalize() Methode erzwingen * Copyright: Copyright © 2002 - free for all use * @author Bastie - Sebastian Ritter * @version 1.0.0.0 */public classTestimplementsNeedToFinalize{/**Konstruktor */publicTest () { System.out.println ("Instanz angelegt:"+this.toString()); }/**Testmethode*/public voidfinalize (){ System.out.println ("Instanz:"+this.toString()+"wird beendet"); }/** Testmethode */public static voidmain (finalString [] ignored){ System.out.println ("3 neue Instanzen anlegen..."); Test t1 =newTest (); Test t2 =newTest (); Test t3 =newTest (); System.out.println ("2 Instanzen registrieren"); ShutdownHook.addNeedToFinalize (t1); ShutdownHook.addNeedToFinalize (t2); System.out.println ("1 registrierte Instanz auf null setzen und den GC starten"); ShutdownHook.removeNeedToFinalize (t2); t2 =null; System.gc ();//Kurz warten, damit der GC läuft!try{Thread.sleep(2000);}catch(InterruptedException ignoredException){} System.out.println ("Anwendung beenden"); System.exit (0); } }