KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > lang > ref > Finalizer


1 /*
2  * @(#)Finalizer.java 1.21 04/09/20
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.lang.ref;
9
10 import java.security.PrivilegedAction JavaDoc;
11 import java.security.AccessController JavaDoc;
12
13
14 final class Finalizer extends FinalReference JavaDoc { /* Package-private; must be in
15                           same package as the Reference
16                           class */

17
18     /* A native method that invokes an arbitrary object's finalize method is
19        required since the finalize method is protected
20      */

21     static native void invokeFinalizeMethod(Object JavaDoc o) throws Throwable JavaDoc;
22
23     static private ReferenceQueue JavaDoc queue = new ReferenceQueue JavaDoc();
24     static private Finalizer JavaDoc unfinalized = null;
25     static private Object JavaDoc lock = new Object JavaDoc();
26
27     private Finalizer JavaDoc
28         next = null,
29     prev = null;
30
31     private boolean hasBeenFinalized() {
32     return (next == this);
33     }
34
35     private void add() {
36     synchronized (lock) {
37         if (unfinalized != null) {
38         this.next = unfinalized;
39         unfinalized.prev = this;
40         }
41         unfinalized = this;
42     }
43     }
44
45     private void remove() {
46     synchronized (lock) {
47         if (unfinalized == this) {
48         if (this.next != null) {
49             unfinalized = this.next;
50         } else {
51             unfinalized = this.prev;
52         }
53         }
54         if (this.next != null) {
55         this.next.prev = this.prev;
56         }
57         if (this.prev != null) {
58         this.prev.next = this.next;
59         }
60         this.next = this; /* Indicates that this has been finalized */
61         this.prev = this;
62     }
63     }
64
65     private Finalizer(Object JavaDoc finalizee) {
66     super(finalizee, queue);
67     add();
68     }
69
70     /* Invoked by VM */
71     static void register(Object JavaDoc finalizee) {
72     new Finalizer JavaDoc(finalizee);
73     }
74
75     private void runFinalizer() {
76     synchronized (this) {
77         if (hasBeenFinalized()) return;
78         remove();
79     }
80     try {
81         Object JavaDoc finalizee = this.get();
82         if (finalizee != null && !(finalizee instanceof java.lang.Enum JavaDoc)) {
83         invokeFinalizeMethod(finalizee);
84         /* Clear stack slot containing this variable, to decrease
85            the chances of false retention with a conservative GC */

86         finalizee = null;
87         }
88     } catch (Throwable JavaDoc x) { }
89     super.clear();
90     }
91
92     /* Create a privileged secondary finalizer thread in the system thread
93        group for the given Runnable, and wait for it to complete.
94
95        This method is used by both runFinalization and runFinalizersOnExit.
96        The former method invokes all pending finalizers, while the latter
97        invokes all uninvoked finalizers if on-exit finalization has been
98        enabled.
99
100        These two methods could have been implemented by offloading their work
101        to the regular finalizer thread and waiting for that thread to finish.
102        The advantage of creating a fresh thread, however, is that it insulates
103        invokers of these methods from a stalled or deadlocked finalizer thread.
104      */

105     private static void forkSecondaryFinalizer(final Runnable JavaDoc proc) {
106     PrivilegedAction JavaDoc pa = new PrivilegedAction JavaDoc() {
107         public Object JavaDoc run() {
108         ThreadGroup JavaDoc tg = Thread.currentThread().getThreadGroup();
109         for (ThreadGroup JavaDoc tgn = tg;
110              tgn != null;
111              tg = tgn, tgn = tg.getParent());
112         Thread JavaDoc sft = new Thread JavaDoc(tg, proc, "Secondary finalizer");
113         sft.start();
114         try {
115             sft.join();
116         } catch (InterruptedException JavaDoc x) {
117             /* Ignore */
118         }
119         return null;
120         }};
121     AccessController.doPrivileged(pa);
122     }
123
124     /* Called by Runtime.runFinalization() */
125     static void runFinalization() {
126     forkSecondaryFinalizer(new Runnable JavaDoc() {
127         public void run() {
128         for (;;) {
129             Finalizer JavaDoc f = (Finalizer JavaDoc)queue.poll();
130             if (f == null) break;
131             f.runFinalizer();
132         }
133         }
134     });
135     }
136
137     /* Invoked by java.lang.Shutdown */
138     static void runAllFinalizers() {
139     forkSecondaryFinalizer(new Runnable JavaDoc() {
140         public void run() {
141         for (;;) {
142             Finalizer JavaDoc f;
143             synchronized (lock) {
144             f = unfinalized;
145             if (f == null) break;
146             unfinalized = f.next;
147             }
148             f.runFinalizer();
149         }}});
150     }
151
152     private static class FinalizerThread extends Thread JavaDoc {
153     FinalizerThread(ThreadGroup JavaDoc g) {
154         super(g, "Finalizer");
155     }
156     public void run() {
157         for (;;) {
158         try {
159             Finalizer JavaDoc f = (Finalizer JavaDoc)queue.remove();
160             f.runFinalizer();
161         } catch (InterruptedException JavaDoc x) {
162             continue;
163         }
164         }
165     }
166     }
167
168     static {
169         ThreadGroup JavaDoc tg = Thread.currentThread().getThreadGroup();
170         for (ThreadGroup JavaDoc tgn = tg;
171              tgn != null;
172              tg = tgn, tgn = tg.getParent());
173     Thread JavaDoc finalizer = new FinalizerThread(tg);
174     finalizer.setPriority(Thread.MAX_PRIORITY - 2);
175     finalizer.setDaemon(true);
176     finalizer.start();
177     }
178
179 }
180
Popular Tags