@@ -22,6 +22,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more
2222import java .lang .ref .ReferenceQueue ;
2323import java .lang .ref .SoftReference ;
2424import java .lang .ref .WeakReference ;
25+ import java .util .concurrent .CountDownLatch ;
26+ import java .util .concurrent .TimeUnit ;
2527import java .lang .ref .PhantomReference ;
2628
2729/**
@@ -34,14 +36,16 @@ Licensed to the Apache Software Foundation (ASF) under one or more
3436 */
3537public class CleanerThread extends Thread {
3638
37- static volatile ReferenceQueue queue = null ;
38- static CleanerThread thread = null ;
39+ static volatile ReferenceQueue <?> queue = null ;
40+ static CleanerThread thread = null ;
41+ /* latch to signal CleanerThread shutdown request */
42+ private CountDownLatch shutdownLatch = new CountDownLatch (1 );
3943
40- public static ReferenceQueue getReferenceQueue () {
44+ public static ReferenceQueue <?> getReferenceQueue () {
4145
42- if ( queue == null ) {
43- synchronized ( CleanerThread . class ) {
44- queue = new ReferenceQueue ();
46+ synchronized ( CleanerThread . class ) {
47+ if ( queue == null ) {
48+ queue = new ReferenceQueue <> ();
4549 thread = new CleanerThread ();
4650 }
4751 }
@@ -94,29 +98,38 @@ public PhantomReferenceCleared(Object o) {
9498
9599 protected CleanerThread () {
96100 super ("Batik CleanerThread" );
97- setDaemon (true );
98101 start ();
99102 }
100103
104+ @ Override
101105 public void run () {
102- while ( true ) {
103- try {
104- Reference ref ;
105- try {
106- ref = queue .remove ();
106+ try {
107+ while (! shutdownLatch . await ( 100 , TimeUnit . SECONDS )) {
108+ Reference <?> ref ;
109+ do {
110+ ref = queue .poll ();
107111 // System.err.println("Cleaned: " + ref);
108- } catch (InterruptedException ie ) {
109- continue ;
110- }
111-
112- if (ref instanceof ReferenceCleared ) {
113- ReferenceCleared rc = (ReferenceCleared )ref ;
114- rc .cleared ();
115- }
116- } catch (ThreadDeath td ) {
117- throw td ;
118- } catch (Throwable t ) {
119- t .printStackTrace ();
112+ if (ref != null && ref instanceof ReferenceCleared ) {
113+ ReferenceCleared rc = (ReferenceCleared )ref ;
114+ rc .cleared ();
115+ }
116+ } while (ref != null );
117+ }
118+ } catch (InterruptedException e ) {
119+ e .printStackTrace ();
120+ }
121+ }
122+
123+ /**
124+ * Request CleanerThread shutdown and wait for it to finish.
125+ */
126+ public static void shutdown () throws InterruptedException {
127+ synchronized (CleanerThread .class ) {
128+ if (thread != null ) {
129+ thread .shutdownLatch .countDown ();
130+ thread .join ();
131+ queue = null ;
132+ thread = null ;
120133 }
121134 }
122135 }
0 commit comments