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.
package
de.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 interface
NeedToFinalize{/** Die Methode finalize wird mit einer Sichtbarkeit public * ausgestattet. */
public void
finalize (); }
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.
package
de.bastie.howto.lang.java;import
java.util.HashSet;import
java.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 class
ShutdownHookimplements
Runnable{private static
ShutdownHook hook;private
ShutdownHook (){};/** 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 static
HashSet objects =new
HashSet ();/** Fügt ein Objekt, welches zwingend ordentlich abgeschlossen werden muss * hinzu. * @param NeetToFinalize object */
public static void
addNeedToFinalize (final
NeedToFinalize needToFinalize){//Singleton Instanz vorhanden?
if
(hook ==null
) { ShutdownHook.hook =new
ShutdownHook ();//Unseren ShutdownHook hinzufügen
Runtime.getRuntime ().addShutdownHook (new
Thread (ShutdownHook.hook)); }//Das übergebende Objekt merken
ShutdownHook.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 void
removeNeedToFinalize (final
NeedToFinalize needToFinalize){ ShutdownHook.objects.remove (needToFinalize); }/** Die hier aufgeführten Aufgaben werden ausgeführt, wenn die JVM Ihren * Shutdown Prozess beginnt. * @pattern MethodDelegate */
public void
run (){this
.finalizeObjects (); }/** Hier rufen wir die finalize Operation für unsere Objekte auf. */
private void
finalizeObjects () {//Besorgen eines Iterationsobjektes
final
Iterator 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.depackage
de.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 class
Testimplements
NeedToFinalize{/**Konstruktor */
public
Test () { System.out.println ("Instanz angelegt:
"+this
.toString()); }/**Testmethode*/
public void
finalize (){ System.out.println ("Instanz:
"+this
.toString()+"wird beendet
"); }/** Testmethode */
public static void
main (final
String [] ignored){ System.out.println ("3 neue Instanzen anlegen...
"); Test t1 =new
Test (); Test t2 =new
Test (); Test t3 =new
Test (); 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
); } }