home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / lang / ref / Finalizer.java next >
Encoding:
Java Source  |  1998-03-20  |  3.4 KB  |  143 lines

  1. /*
  2.  * @(#)Finalizer.java    1.10 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang.ref;
  16.  
  17.  
  18. final class Finalizer extends FinalReference { /* Package-private; must be in
  19.                           same package as the Reference
  20.                           class */
  21.  
  22.     /* A native method that invokes an arbitrary object's finalize method is
  23.        required since the finalize method is protected */
  24.     static native void invokeFinalizeMethod(Object o) throws Throwable;
  25.  
  26.     static private ReferenceQueue queue = new ReferenceQueue();
  27.     static private Finalizer unfinalized = null;
  28.  
  29.     private Finalizer
  30.         next = null,
  31.     prev = null;
  32.     static private Object lock = new Object();
  33.  
  34.     private boolean hasBeenFinalized() {
  35.     return (next == this);
  36.     }
  37.  
  38.     private void add() {
  39.     synchronized (lock) {
  40.         if (unfinalized != null) {
  41.         this.next = unfinalized;
  42.         unfinalized.prev = this;
  43.         }
  44.         unfinalized = this;
  45.     }
  46.     }
  47.  
  48.     private void remove() {
  49.     synchronized (lock) {
  50.         if (unfinalized == this) {
  51.         if (this.next != null) {
  52.             unfinalized = this.next;
  53.         } else {
  54.             unfinalized = this.prev;
  55.         }
  56.         }
  57.         if (this.next != null) {
  58.         this.next.prev = this.prev;
  59.         }
  60.         if (this.prev != null) {
  61.         this.prev.next = this.next;
  62.         }
  63.         this.next = this;    /* Indicates that this has been finalized */
  64.         this.prev = this;
  65.     }
  66.     }
  67.  
  68.     private Finalizer(Object finalizee) {
  69.     super(finalizee, queue);
  70.     add();
  71.     }
  72.  
  73.     static void register(Object finalizee) { /* Invoked by VM */
  74.     new Finalizer(finalizee);
  75.     }
  76.  
  77.     synchronized private void runFinalizer() {
  78.     if (!hasBeenFinalized()) {
  79.         try {
  80.         Object finalizee = this.get();
  81.         if (finalizee != null) {
  82.             invokeFinalizeMethod(finalizee);
  83.             finalizee = null;
  84.         }
  85.         } catch (Throwable x) { }
  86.         remove();
  87.         super.clear();
  88.     }
  89.     }
  90.  
  91.     /* Called by Runtime.runFinalization() */
  92.     /* ## REMIND: Finalizers should be run in a clean thread */
  93.     static void runFinalization() {
  94.     for (;;) {
  95.         Finalizer f = (Finalizer)queue.poll();
  96.         if (f == null) break;
  97.         f.runFinalizer();
  98.     }
  99.     }
  100.  
  101.     private static boolean runOnExit = false;
  102.  
  103.     /* Called by Runtime.runFinalizersOnExit */
  104.     static void setRunFinalizersOnExit(boolean value) {
  105.     runOnExit = value;
  106.     }
  107.  
  108.     /* Called on exit by the VM */
  109.     /* ## REMIND: Finalizers should be run in a clean thread */
  110.     static void runFinalizersOnExit() {
  111.     if (! runOnExit) return;
  112.     Finalizer f, nf;
  113.     for (f = unfinalized; f != null; f = nf) {
  114.         nf = f.next;
  115.         f.runFinalizer();
  116.     }
  117.     }
  118.  
  119.     static private Thread finalizer = new FinalizerThread();
  120.  
  121.     private static class FinalizerThread extends Thread {
  122.     public void run() {
  123.         for (;;) {
  124.         try {
  125.             Finalizer f = (Finalizer)queue.remove();
  126.             f.runFinalizer();
  127.         } catch (InterruptedException x) {
  128.             continue;
  129.         }
  130.         }
  131.     }
  132.     }
  133.  
  134.     static {
  135.     finalizer.setName("Finalizer");
  136.     /* ## REMIND: Temporary until finalizer priority-boosting works */
  137.     finalizer.setPriority(Thread.MAX_PRIORITY - 2);
  138.     finalizer.setDaemon(true);
  139.     finalizer.start();
  140.     }
  141.  
  142. }
  143.