Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


4.11.6

Referenzklassen



[1.2]Bis zum JDK 1.1 konnten Objekte in Java nur mit starken Referenzen referenziert werden. Schwache Referenzen, wie es sie beispielsweise auch in Smalltalk gibt, fehlten bislang. Diese Lücke wurde im JDK 1.2 durch die Referenzklassen im neuen Paket java.lang.ref geschlossen.

Die bisher bekannten Verweise (Referenzen) auf Objekte nennt man auch starke Referenzen, weil sie den Garbage Collector daran hindern, das referenzierte Objekt zu entfernen. Im Gegensatz dazu verhindern schwache Referenzen die Freigabe des Objekts nicht.

Anwendungsfälle für schwache Referenzen sind unter anderem: Schwache Referenzen werden von Klassen dargestellt, die alle von der abstrakten Klasse java.lang.ref.Reference abgeleitet sind. Diese Klassen werden im folgenden Referenzklassen genannt. Eine schwache Referenz auf ein Objekt wird erzeugt, in dem eine starke Referenz darauf im Konstruktor einer Referenzklasse übergeben wird:
  Object anObject = new Object();
  WeakReference ref = new WeakReference(anObject);
So erzeugte Referenzobjekte kapseln also immer eine schwache Referenz auf ein bestimmtes Objekt. Alle Unterklassen von Reference verfügen über die geerbten Methoden get(), mit der das referenzierte Objekt abgerufen werden kann, sowie clear(), mit der die schwache Referenz gelöscht wird. Neben WeakReference gibt es noch die Klasssen PhantomReference und SoftReference.

Mit einer zweiten Konstruktorvariante können Referenzobjekte zusätzlich einer Warteschlange zugeordnet werden. Diese Warteschlangen werden von der Klasse ReferenceQueue repräsentiert:
  Object anObject = new Object();
  ReferenceQueue queue = new ReferenceQueue();
  WeakReference ref = new WeakReference(anObject, queue);
In diesem Fall wird das Referenzobjekt in seine Warteschlange eingetragen, wenn das referenzierte Objekt zur Beseitigung ansteht. Durch Abfragen dieser Warteschlange (z.B. in einem eigenen Thread) kann ein Programm die erforderlichen Abschlussaktionen durchführen. Zu diesem Zweck stellt ReferenceQueue die Methode remove() zur Verfügung. Sie entfernt das erste Referenzobjekt in der Warteschlange und liefert es zurück. Wenn die Schlange momentan leer ist, blockiert sie so lange, bis der Garbage Collector ein neues Referenzobjekt einträgt. Daneben gibt es noch die nicht blockierende Methode poll(), die keinen eigenen Thread erfordert. Falls sie eine leere Schlange vorfindet, kehrt sie sofort zurück und liefert einfach null.

Durch die Einführung der Referenzklassen werden nunmehr vier verschiedene Arten von Referenzen unterschieden. Nachfolgend sind die einzelnen Typen vom stärksten zum schwächsten Typ aufgeführt:

Ein Beispiel: Objekt-Cache

SoftReference-Objekte können beispielsweise in einem Applet verwendet werden, das Datensätze eines Produktkatalogs von einem Datenbankserver bezieht. Da die Übertragung über das Netz insbesondere bei großen Datensätzen einen erheblichen Teil der Antwortzeit ausmacht, lohnt es sich, die bereits abgerufenen Datensätze in einem Cache zu halten, solange der verbleibende Hauptspeicher des Clients groß genug ist. Wurde die Cache-Referenz dagegen aufgrund geringen Hauptspeichers in der Zwischenzeit wieder gelöscht, muss der benötigte Datensatz eben wieder vom Server geholt werden.

Der folgende Auszug zeigt, wie man einen Objekt-Cache unter Verwendung der Klasse SoftReference implementieren kann. Beim Ablegen eines Objekts im Cache wird ein SoftReference-Objekt in einer Hashtable abgelegt:
  cache = new Hashtable();
  ...
  void store(Record record) {
    cache.put(new Integer(record.number),
              new SoftReference(record));
  }

Beim Abrufen eines Objekts aus dem Cache muss zunächst festgestellt werden, ob das Objekt im Cache vorhanden ist (Cache Hit) oder nicht (Cache Miss). Ein Cache Miss liegt vor, wenn der Schlüssel nicht in der Tabelle vorhanden ist, aber auch dann, wenn der Schlüssel zwar existiert, aber das referenzierte Objekt in der Zwischenzeit vom Garbage Collector entfernt wurde. Deswegen muss nach dem Abrufen des Referenzobjekts zusätzlich geprüft werden, ob dessen get()-Methode null liefert.
  Record retrieve(int key) {
    SoftReference ref;

    ref = (SoftReference)cache.get(new Integer(key));

    if (ref == null)
      // Cache miss
      return null;
    else {
      // Cache hit
      Record rec;
      rec = (Record)ref.get();
      // Objekt mittlerweile entfernt ?
      if (rec == null) {
        // Eintrag löschen
        cache.remove(new Integer(key));
      }
      return rec;
    }
  }

Das komplette Beispiel befindet sich auf der CD und besteht aus einem Server, der die Daten bereitstellt und dem in Abbildung 4.6 dargestellten Applet, das die Daten über eine Socket-Verbindung von diesem Server holt. Im Eingabefeld kann eine Artikelnummer eingegeben werden, z. B. »1«. Durch Drücken des Buttons wird der dazugehörige Datensatz geholt, und zwar beim ersten Mal vom Server, bei weiteren Zugriffen aus dem Cache. Die Quelle, aus der das Objekt bezogen wurde, wird am unteren Rand angezeigt.

Abbildung 4.6: Zugriff auf einen Buchkatalog mit clientseitigem Cache
Abbildung 4.6


Material zum Beispiel


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.