CONTENT | PREV | NEXT

3.2 Ein kleines Beispiel

 
import java.util.HashMap;
import java.lang.ref.*;

/**
*       Ein einfacher Cache basierend auf SoftReferences. Es obliegt der vollen
*       Kontrolle des Garbage Collectors wann welche Einträge aus dem Cache
*       entfernt werden.
*       @author Sven Buergel
*       @version 0.1
*/

public class Cache {

        /**
        *       CacheReferences halten als Referent das zu speichernde Objekt.
        *       Zusätzlich zum Referent wird noch ein Schlüsselobjekt gespeichert,
        *       um später verwaiste Einträge aus dem Cache zu entfernen.
        */

        protected class CacheReference extends SoftReference {

                /**
                *       der zusätzliche Schlüssel
                */

                private Object key;

                /**
                *       Erzeugt eine neue CacheReference
                *       @param key der Schlüssel des Eintrages
                *       @param value das zu cachende Objekt
                *       @param q eine ReferenceQueue
                */

                public CacheReference(Object key, Object value, ReferenceQueue q) {

                        super(value,q);
                        this.key=key;

                }

                /**
                *       Liefert den Schlüssel des Eintrages.
                */

                public Object getKey() {

                        return key;

                }

                public boolean equals(Object o) {

                        return (o!=null) &&
                                (o instanceof CacheReference) &&
                                (key.equals(((CacheReference)o).getKey()));

                }

                public int hashCode() {

                        return key.hashCode();

                }

        }

        /**
        *       der eigentliche Speicher
        */

        private HashMap hash;

        /**
        *       ReferenceQueue zum Auffangen von freigegebenen CacheReferences
        */

        private ReferenceQueue queue;

        /**
        *       Erzeugt einen neuen Cache. Die Cachegröße variiert und kann
        *       maximal den gesamten Heap einnehmen.
        */

        public Cache() {

                hash=new HashMap();
                queue=new ReferenceQueue();

        }

        /**
        *       Fügt hinzu oder ersetzt einen Cacheeintrag.
        *       @param key der Key des Eintrages
        *       @param value der Wert des Eintrages
        *       @return ein evtl. schon vorhandener Wert unter diesem Key
        */

        public Object put(Object key, Object value) {

                processQueue();
                Object tmp=null;
                if ((key!=null) && (value!=null)) {
                        tmp=hash.put(key,new CacheReference(key,value,queue));
                }
                return tmp;

        }

        /**
        *       Liefert den zugehörigen Cacheeintrag oder <code>null</code>, falls
        *       kein passender Eintrag mehr existiert.
        *       @param key der Schlüssel des Eintrages
        *       @return den Wert des Eintrages
        */

        public Object get(Object key) {

                Reference ref=(Reference)hash.get(key);
                return (ref==null) ? null : ref.get();

        }

        /**
        *       Pollt die ReferenceQueue nach freigegebenen CacheReferences.
        *       Sobald ein Cacheobjekt vom Garbage Collector gelöscht wurde,
        *       wird auch der verwaiste Cacheeintrag entfernt.
        */

        protected void processQueue() {

                CacheReference ref;
                while ((ref=(CacheReference)queue.poll())!=null) {
                        hash.remove(ref.getKey());
                }

        }

}

Cache.java

 
© 1999 sven.buergel@informatik.tu-chemnitz.de