001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.util;
020:
021: import java.lang.ref.Reference;
022: import java.lang.ref.ReferenceQueue;
023: import java.lang.ref.SoftReference;
024: import java.lang.ref.WeakReference;
025: import java.lang.ref.PhantomReference;
026:
027: /**
028: * One line Class Desc
029: *
030: * Complete Class Desc
031: *
032: * @author <a href="mailto:deweese@apache.org">l449433</a>
033: * @version $Id: CleanerThread.java 489226 2006-12-21 00:05:36Z cam $
034: */
035: public class CleanerThread extends Thread {
036:
037: static volatile ReferenceQueue queue = null;
038: static CleanerThread thread = null;
039:
040: public static ReferenceQueue getReferenceQueue() {
041:
042: if (queue == null) {
043: synchronized (CleanerThread.class) {
044: queue = new ReferenceQueue();
045: thread = new CleanerThread();
046: }
047: }
048: return queue;
049: }
050:
051: /**
052: * If objects registered with the reference queue associated with
053: * this class implement this interface then the 'cleared' method
054: * will be called when the reference is queued.
055: */
056: public static interface ReferenceCleared {
057: /* Called when the reference is cleared */
058: void cleared();
059: }
060:
061: /**
062: * A SoftReference subclass that automatically registers with
063: * the cleaner ReferenceQueue.
064: */
065: public abstract static class SoftReferenceCleared extends
066: SoftReference implements ReferenceCleared {
067: public SoftReferenceCleared(Object o) {
068: super (o, CleanerThread.getReferenceQueue());
069: }
070: }
071:
072: /**
073: * A WeakReference subclass that automatically registers with
074: * the cleaner ReferenceQueue.
075: */
076: public abstract static class WeakReferenceCleared extends
077: WeakReference implements ReferenceCleared {
078: public WeakReferenceCleared(Object o) {
079: super (o, CleanerThread.getReferenceQueue());
080: }
081: }
082:
083: /**
084: * A PhantomReference subclass that automatically registers with
085: * the cleaner ReferenceQueue.
086: */
087: public abstract static class PhantomReferenceCleared extends
088: PhantomReference implements ReferenceCleared {
089: public PhantomReferenceCleared(Object o) {
090: super (o, CleanerThread.getReferenceQueue());
091: }
092: }
093:
094: protected CleanerThread() {
095: setDaemon(true);
096: start();
097: }
098:
099: public void run() {
100: while (true) {
101: try {
102: Reference ref;
103: try {
104: ref = queue.remove();
105: // System.err.println("Cleaned: " + ref);
106: } catch (InterruptedException ie) {
107: continue;
108: }
109:
110: if (ref instanceof ReferenceCleared) {
111: ReferenceCleared rc = (ReferenceCleared) ref;
112: rc.cleared();
113: }
114: } catch (ThreadDeath td) {
115: throw td;
116: } catch (Throwable t) {
117: t.printStackTrace();
118: }
119: }
120: }
121: }
|