Skip to content

Commit e0f777e

Browse files
jjYBdx4ILjjYBdx4IL
authored andcommitted
shutdown() function for CleanerThread:
* de-initialize CleanerThread variables on thread shutdown * don't run CleanerThread as daemon
1 parent f79ce60 commit e0f777e

File tree

2 files changed

+42
-24
lines changed

2 files changed

+42
-24
lines changed

batik-util/src/main/java/org/apache/batik/util/CleanerThread.java

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more
2222
import java.lang.ref.ReferenceQueue;
2323
import java.lang.ref.SoftReference;
2424
import java.lang.ref.WeakReference;
25+
import java.util.concurrent.CountDownLatch;
26+
import java.util.concurrent.TimeUnit;
2527
import java.lang.ref.PhantomReference;
2628

2729
/**
@@ -34,15 +36,18 @@ Licensed to the Apache Software Foundation (ASF) under one or more
3436
*/
3537
public class CleanerThread extends Thread {
3638

37-
static volatile ReferenceQueue queue = null;
39+
static volatile ReferenceQueue<?> queue = null;
3840
static CleanerThread thread = null;
41+
/* latch to signal CleanerThread shutdown request */
42+
private static CountDownLatch shutdownLatch = null;
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();
50+
shutdownLatch = new CountDownLatch(1);
4651
}
4752
}
4853
return queue;
@@ -94,29 +99,42 @@ public PhantomReferenceCleared(Object o) {
9499

95100
protected CleanerThread() {
96101
super("Batik CleanerThread");
97-
setDaemon(true);
98102
start();
99103
}
100104

105+
@Override
101106
public void run() {
102-
while(true) {
103-
try {
104-
Reference ref;
105-
try {
106-
ref = queue.remove();
107+
try {
108+
while(!shutdownLatch.await(100, TimeUnit.SECONDS)) {
109+
Reference<?> ref;
110+
do {
111+
ref = queue.poll();
107112
// 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();
113+
if (ref != null && ref instanceof ReferenceCleared) {
114+
ReferenceCleared rc = (ReferenceCleared)ref;
115+
rc.cleared();
116+
}
117+
} while (ref != null);
118+
}
119+
} catch (InterruptedException e) {
120+
e.printStackTrace();
121+
} finally {
122+
synchronized (CleanerThread.class) {
123+
queue = null;
124+
thread = null;
125+
shutdownLatch = null;
126+
}
127+
}
128+
}
129+
130+
/**
131+
* Request CleanerThread shutdown and wait for it to finish.
132+
*/
133+
public static void shutdown() throws InterruptedException {
134+
synchronized (CleanerThread.class) {
135+
if (shutdownLatch != null) {
136+
shutdownLatch.countDown();
137+
thread.join();
120138
}
121139
}
122140
}

batik-util/src/main/java/org/apache/batik/util/HaltingThread.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public class HaltingThread extends Thread {
3131
/**
3232
* Boolean indicating if this thread has ever been 'halted'.
3333
*/
34-
protected boolean beenHalted = false;
34+
protected volatile boolean beenHalted = false;
3535

3636
public HaltingThread() { }
3737

0 commit comments

Comments
 (0)