src/share/classes/java/lang/ref/Finalizer.java
Print this page
rev 670 : 8003335: Better handling of Finalizer thread
Reviewed-by: alanb, ahgross
@@ -36,13 +36,13 @@
/* A native method that invokes an arbitrary object's finalize method is
required since the finalize method is protected
*/
static native void invokeFinalizeMethod(Object o) throws Throwable;
- static private ReferenceQueue queue = new ReferenceQueue();
- static private Finalizer unfinalized = null;
- static private Object lock = new Object();
+ private static ReferenceQueue queue = new ReferenceQueue();
+ private static Finalizer unfinalized = null;
+ private static final Object lock = new Object();
private Finalizer
next = null,
prev = null;
@@ -140,11 +140,15 @@
}
/* Called by Runtime.runFinalization() */
static void runFinalization() {
forkSecondaryFinalizer(new Runnable() {
+ private volatile boolean running;
public void run() {
+ if (running)
+ return;
+ running = true;
for (;;) {
Finalizer f = (Finalizer)queue.poll();
if (f == null) break;
f.runFinalizer();
}
@@ -153,11 +157,15 @@
}
/* Invoked by java.lang.Shutdown */
static void runAllFinalizers() {
forkSecondaryFinalizer(new Runnable() {
+ private volatile boolean running;
public void run() {
+ if (running)
+ return;
+ running = true;
for (;;) {
Finalizer f;
synchronized (lock) {
f = unfinalized;
if (f == null) break;
@@ -166,14 +174,18 @@
f.runFinalizer();
}}});
}
private static class FinalizerThread extends Thread {
+ private volatile boolean running;
FinalizerThread(ThreadGroup g) {
super(g, "Finalizer");
}
public void run() {
+ if (running)
+ return;
+ running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
f.runFinalizer();
} catch (InterruptedException x) {