Index: sources/org/apache/batik/util/CleanerThread.java =================================================================== --- sources/org/apache/batik/util/CleanerThread.java (revision 911532) +++ sources/org/apache/batik/util/CleanerThread.java (working copy) @@ -34,17 +34,10 @@ */ public class CleanerThread extends Thread { - static volatile ReferenceQueue queue = null; - static CleanerThread thread = null; - - public static ReferenceQueue getReferenceQueue() { + volatile ReferenceQueue queue; + public static final CleanerThread THREAD = new CleanerThread(); - if ( queue == null ) { - synchronized (CleanerThread.class) { - queue = new ReferenceQueue(); - thread = new CleanerThread(); - } - } + public synchronized ReferenceQueue getReferenceQueue() { return queue; } @@ -65,7 +58,7 @@ public abstract static class SoftReferenceCleared extends SoftReference implements ReferenceCleared { public SoftReferenceCleared(Object o) { - super (o, CleanerThread.getReferenceQueue()); + super (o, THREAD.getReferenceQueue()); } } @@ -76,7 +69,7 @@ public abstract static class WeakReferenceCleared extends WeakReference implements ReferenceCleared { public WeakReferenceCleared(Object o) { - super (o, CleanerThread.getReferenceQueue()); + super (o, THREAD.getReferenceQueue()); } } @@ -88,22 +81,24 @@ extends PhantomReference implements ReferenceCleared { public PhantomReferenceCleared(Object o) { - super (o, CleanerThread.getReferenceQueue()); + super (o, THREAD.getReferenceQueue()); } } protected CleanerThread() { super("Batik CleanerThread"); + queue = new ReferenceQueue(); setDaemon(true); start(); } public void run() { - while(true) { + ReferenceQueue rq; + while ((rq = getReferenceQueue ()) != null) { try { Reference ref; try { - ref = queue.remove(); + ref = rq.remove(); // System.err.println("Cleaned: " + ref); } catch (InterruptedException ie) { continue; @@ -120,4 +115,24 @@ } } } + + /** + * Stops the cleaner thread. Calling this method is recommended in all long running applications + * with custom class loaders (e.g., web applications). + */ + public void exit() { + // try to stop it gracefully + synchronized (this) { + queue = null; + } + this.interrupt(); + try { + this.join(500); + } catch (InterruptedException e) { + + } + // last resort tentative to kill the cleaner thread + if (this.isAlive()) + this.stop(); + } }