Vergleichen von Objekten


Wie erzwinge ich die Auführung der finalize() Methode?

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 ShutdownHook implements 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.

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
 */

public class Test implements 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);
  }
}

all rights reserved © Bastie - Sebastian Ritter @: w³: http://www.Bastie.de
Diese Seite ist Bestandteil der Internetpräsenz unter http://www.Bastie.de


Java Cobol Software Resourcen Service Links Über mich Zum Gästebuch Forum