001: /*
002: * CacheCleaner.java February 2001
003: *
004: * Copyright (C) 2001, Niall Gallagher <niallg@users.sf.net>
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General
016: * Public License along with this library; if not, write to the
017: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
018: * Boston, MA 02111-1307 USA
019: */
020:
021: package simple.util.cache;
022:
023: import simple.util.schedule.Scheduler;
024:
025: /**
026: * This is used to asynchronously remove objects from the cache when
027: * those objects timeout. This uses the <code>Scheduler</code> that
028: * the <code>TimeCache</code> uses to store the timeouts of objects
029: * that are in the <code>TimeCache</code>. This is an active object
030: * and an instance of this will automatically start a thread.
031: *
032: * @author Niall Gallagher
033: */
034: final class CacheCleaner implements Runnable {
035:
036: /**
037: * This is the time cache that is to to be cleaned by this.
038: */
039: private TimeCache cache;
040:
041: /**
042: * This refers to the stale objects in the time cache.
043: */
044: private Scheduler queue;
045:
046: /**
047: * This allows the cleaner to run concurrently.
048: */
049: protected Thread thread;
050:
051: /**
052: * This will start a thread to remove each stale item. The
053: * cache instance this will be cleaning must be provided.
054: *
055: * @param cache the time cache that this is cleaning
056: * @param queue the queue that contains stale items
057: */
058: public CacheCleaner(TimeCache cache, Scheduler queue) {
059: this .thread = new Thread(this );
060: this .cache = cache;
061: this .queue = queue;
062: this .thread.start();
063: }
064:
065: /**
066: * This is a driver for the clean method to dequeue and
067: * remove objects that have timed out. This will catch any
068: * exceptions that propagate from the clean method, however
069: * this is unlikely because the thread that is dequeuing is
070: * private and the only exception is InterruptedException.
071: */
072: public void run() {
073: while (true) {
074: try {
075: clean();
076: } catch (Exception e) {
077: e.printStackTrace();
078: }
079: }
080: }
081:
082: /**
083: * This dequeues and removes the stale objects in the
084: * <code>TimeCache</code>. This will remove items from the
085: * <code>TimeCache</code> only if the item that is to be
086: * removed exists within the cache, see
087: * <code>CacheReference</code>.
088: *
089: * @exception InterruptedException this unlikely to happen
090: */
091: public void clean() throws InterruptedException {
092: Object stale = queue.dequeue();
093: CacheReference ref = (CacheReference) stale;
094: Object cached = ref.get();
095:
096: if (cached != null && cached == cache.lookup(ref)) {
097: cache.remove(ref);
098: }
099: }
100: }
|