Lines 34-50
Link Here
|
34 |
*/ |
34 |
*/ |
35 |
public class CleanerThread extends Thread { |
35 |
public class CleanerThread extends Thread { |
36 |
|
36 |
|
37 |
static volatile ReferenceQueue queue = null; |
37 |
volatile ReferenceQueue queue; |
38 |
static CleanerThread thread = null; |
38 |
|
39 |
|
39 |
/** |
40 |
public static ReferenceQueue getReferenceQueue() { |
40 |
* Singleton instance of CleanerThread. |
|
|
41 |
*/ |
42 |
public static final CleanerThread THREAD = new CleanerThread(); |
41 |
|
43 |
|
42 |
if ( queue == null ) { |
44 |
public synchronized ReferenceQueue getReferenceQueue() { |
43 |
synchronized (CleanerThread.class) { |
|
|
44 |
queue = new ReferenceQueue(); |
45 |
thread = new CleanerThread(); |
46 |
} |
47 |
} |
48 |
return queue; |
45 |
return queue; |
49 |
} |
46 |
} |
50 |
|
47 |
|
Lines 65-71
Link Here
|
65 |
public abstract static class SoftReferenceCleared extends SoftReference |
62 |
public abstract static class SoftReferenceCleared extends SoftReference |
66 |
implements ReferenceCleared { |
63 |
implements ReferenceCleared { |
67 |
public SoftReferenceCleared(Object o) { |
64 |
public SoftReferenceCleared(Object o) { |
68 |
super (o, CleanerThread.getReferenceQueue()); |
65 |
super (o, THREAD.getReferenceQueue()); |
69 |
} |
66 |
} |
70 |
} |
67 |
} |
71 |
|
68 |
|
Lines 76-82
Link Here
|
76 |
public abstract static class WeakReferenceCleared extends WeakReference |
73 |
public abstract static class WeakReferenceCleared extends WeakReference |
77 |
implements ReferenceCleared { |
74 |
implements ReferenceCleared { |
78 |
public WeakReferenceCleared(Object o) { |
75 |
public WeakReferenceCleared(Object o) { |
79 |
super (o, CleanerThread.getReferenceQueue()); |
76 |
super (o, THREAD.getReferenceQueue()); |
80 |
} |
77 |
} |
81 |
} |
78 |
} |
82 |
|
79 |
|
Lines 88-109
Link Here
|
88 |
extends PhantomReference |
85 |
extends PhantomReference |
89 |
implements ReferenceCleared { |
86 |
implements ReferenceCleared { |
90 |
public PhantomReferenceCleared(Object o) { |
87 |
public PhantomReferenceCleared(Object o) { |
91 |
super (o, CleanerThread.getReferenceQueue()); |
88 |
super (o, THREAD.getReferenceQueue()); |
92 |
} |
89 |
} |
93 |
} |
90 |
} |
94 |
|
91 |
|
95 |
protected CleanerThread() { |
92 |
protected CleanerThread() { |
96 |
super("Batik CleanerThread"); |
93 |
super("Batik CleanerThread"); |
|
|
94 |
queue = new ReferenceQueue(); |
97 |
setDaemon(true); |
95 |
setDaemon(true); |
98 |
start(); |
96 |
start(); |
99 |
} |
97 |
} |
100 |
|
98 |
|
101 |
public void run() { |
99 |
public void run() { |
102 |
while(true) { |
100 |
ReferenceQueue rq; |
|
|
101 |
while((rq = getReferenceQueue ()) != null) { |
103 |
try { |
102 |
try { |
104 |
Reference ref; |
103 |
Reference ref; |
105 |
try { |
104 |
try { |
106 |
ref = queue.remove(); |
105 |
ref = rq.remove(); |
107 |
// System.err.println("Cleaned: " + ref); |
106 |
// System.err.println("Cleaned: " + ref); |
108 |
} catch (InterruptedException ie) { |
107 |
} catch (InterruptedException ie) { |
109 |
continue; |
108 |
continue; |
Lines 120-123
Link Here
|
120 |
} |
119 |
} |
121 |
} |
120 |
} |
122 |
} |
121 |
} |
123 |
} |
122 |
|
|
|
123 |
/** |
124 |
* Stops the cleaner thread. Calling this method is recommended in all long running applications |
125 |
* with custom class loaders (e.g., web applications). |
126 |
*/ |
127 |
public void exit() { |
128 |
// try to stop it gracefully |
129 |
synchronized (this) { |
130 |
queue = null; |
131 |
} |
132 |
this.interrupt(); |
133 |
try { |
134 |
this.join(500); |
135 |
} catch (InterruptedException e) { |
136 |
// join failed |
137 |
} |
138 |
// last resort tentative to kill the cleaner thread |
139 |
if (this.isAlive()) |
140 |
this.stop(); |
141 |
} |
142 |
} |