< prev index next >

src/java.base/share/classes/java/lang/ref/Finalizer.java

Print this page

 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.lang.ref;
 27 
 28 import java.security.PrivilegedAction;
 29 import java.security.AccessController;
 30 import jdk.internal.access.JavaLangAccess;
 31 import jdk.internal.access.SharedSecrets;
 32 import jdk.internal.misc.VM;
 33 
 34 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
 35                                                           same package as the Reference
 36                                                           class */
 37 
 38     private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
 39 
 40     /** Head of doubly linked list of Finalizers awaiting finalization. */
 41     private static Finalizer unfinalized = null;
 42 
 43     /** Lock guarding access to unfinalized list. */
 44     private static final Object lock = new Object();
 45 
 46     private Finalizer next, prev;
 47 
 48     private Finalizer(Object finalizee) {
 49         super(finalizee, queue);
 50         // push onto unfinalized
 51         synchronized (lock) {
 52             if (unfinalized != null) {
 53                 this.next = unfinalized;
 54                 unfinalized.prev = this;
 55             }
 56             unfinalized = this;
 57         }
 58     }

 96         super.clear();
 97     }
 98 
 99     private static native void reportComplete(Object finalizee);
100 
101     /* Create a privileged secondary finalizer thread in the system thread
102      * group for the given Runnable, and wait for it to complete.
103      *
104      * This method is used by runFinalization.
105      *
106      * It could have been implemented by offloading the work to the
107      * regular finalizer thread and waiting for that thread to finish.
108      * The advantage of creating a fresh thread, however, is that it insulates
109      * invokers of that method from a stalled or deadlocked finalizer thread.
110      */
111     @SuppressWarnings("removal")
112     private static void forkSecondaryFinalizer(final Runnable proc) {
113         AccessController.doPrivileged(
114             new PrivilegedAction<>() {
115                 public Void run() {

116                     ThreadGroup tg = Thread.currentThread().getThreadGroup();
117                     for (ThreadGroup tgn = tg;
118                          tgn != null;
119                          tg = tgn, tgn = tg.getParent());
120                     Thread sft = new Thread(tg, proc, "Secondary finalizer", 0, false);
121                     sft.start();
122                     try {
123                         sft.join();
124                     } catch (InterruptedException x) {
125                         Thread.currentThread().interrupt();
126                     }
127                     return null;
128                 }});
129     }
130 
131     /* Called by Runtime.runFinalization() */
132     static void runFinalization() {
133         if (VM.initLevel() == 0) {
134             return;
135         }

165                 try {
166                     VM.awaitInitLevel(1);
167                 } catch (InterruptedException x) {
168                     // ignore and continue
169                 }
170             }
171             final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
172             running = true;
173             for (;;) {
174                 try {
175                     Finalizer f = (Finalizer)queue.remove();
176                     f.runFinalizer(jla);
177                 } catch (InterruptedException x) {
178                     // ignore and continue
179                 }
180             }
181         }
182     }
183 
184     static {

185         ThreadGroup tg = Thread.currentThread().getThreadGroup();
186         for (ThreadGroup tgn = tg;
187              tgn != null;
188              tg = tgn, tgn = tg.getParent());
189         Thread finalizer = new FinalizerThread(tg);
190         finalizer.setPriority(Thread.MAX_PRIORITY - 2);
191         finalizer.setDaemon(true);
192         finalizer.start();
193     }
194 
195 }

 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.lang.ref;
 27 
 28 import java.security.PrivilegedAction;
 29 import java.security.AccessController;
 30 import jdk.internal.access.JavaLangAccess;
 31 import jdk.internal.access.SharedSecrets;
 32 import jdk.internal.misc.VM;
 33 
 34 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
 35                                                           same package as the Reference
 36                                                           class */
 37 
 38     private static ReferenceQueue<Object> queue = new NativeReferenceQueue<>();
 39 
 40     /** Head of doubly linked list of Finalizers awaiting finalization. */
 41     private static Finalizer unfinalized = null;
 42 
 43     /** Lock guarding access to unfinalized list. */
 44     private static final Object lock = new Object();
 45 
 46     private Finalizer next, prev;
 47 
 48     private Finalizer(Object finalizee) {
 49         super(finalizee, queue);
 50         // push onto unfinalized
 51         synchronized (lock) {
 52             if (unfinalized != null) {
 53                 this.next = unfinalized;
 54                 unfinalized.prev = this;
 55             }
 56             unfinalized = this;
 57         }
 58     }

 96         super.clear();
 97     }
 98 
 99     private static native void reportComplete(Object finalizee);
100 
101     /* Create a privileged secondary finalizer thread in the system thread
102      * group for the given Runnable, and wait for it to complete.
103      *
104      * This method is used by runFinalization.
105      *
106      * It could have been implemented by offloading the work to the
107      * regular finalizer thread and waiting for that thread to finish.
108      * The advantage of creating a fresh thread, however, is that it insulates
109      * invokers of that method from a stalled or deadlocked finalizer thread.
110      */
111     @SuppressWarnings("removal")
112     private static void forkSecondaryFinalizer(final Runnable proc) {
113         AccessController.doPrivileged(
114             new PrivilegedAction<>() {
115                 public Void run() {
116                     @SuppressWarnings("deprecation")
117                     ThreadGroup tg = Thread.currentThread().getThreadGroup();
118                     for (ThreadGroup tgn = tg;
119                          tgn != null;
120                          tg = tgn, tgn = tg.getParent());
121                     Thread sft = new Thread(tg, proc, "Secondary finalizer", 0, false);
122                     sft.start();
123                     try {
124                         sft.join();
125                     } catch (InterruptedException x) {
126                         Thread.currentThread().interrupt();
127                     }
128                     return null;
129                 }});
130     }
131 
132     /* Called by Runtime.runFinalization() */
133     static void runFinalization() {
134         if (VM.initLevel() == 0) {
135             return;
136         }

166                 try {
167                     VM.awaitInitLevel(1);
168                 } catch (InterruptedException x) {
169                     // ignore and continue
170                 }
171             }
172             final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
173             running = true;
174             for (;;) {
175                 try {
176                     Finalizer f = (Finalizer)queue.remove();
177                     f.runFinalizer(jla);
178                 } catch (InterruptedException x) {
179                     // ignore and continue
180                 }
181             }
182         }
183     }
184 
185     static {
186         @SuppressWarnings("deprecation")
187         ThreadGroup tg = Thread.currentThread().getThreadGroup();
188         for (ThreadGroup tgn = tg;
189              tgn != null;
190              tg = tgn, tgn = tg.getParent());
191         Thread finalizer = new FinalizerThread(tg);
192         finalizer.setPriority(Thread.MAX_PRIORITY - 2);
193         finalizer.setDaemon(true);
194         finalizer.start();
195     }
196 
197 }
< prev index next >