java.lang.ref.Finalizer

package java.lang.ref;

import java.security.PrivilegedAction;
import java.security.AccessController;

// comment by liqiang

final class Finalizer extends FinalReference { //包内使用的类

    /*
     * 一个本地方法 用来调用任意Object对象的finalize方法,因为Object对象的finalize方法
     * 为protected,不能直接调用
     */
    static native void invokeFinalizeMethod(Object o) throws Throwable;

    //引用队列,为static
    static private ReferenceQueue queue = new ReferenceQueue();
    static private Finalizer unfinalized = null;
    //锁对象
    static private Object lock = new Object();

    //对象的上一对象,和下一对象,队列使用双向
    private Finalizer
        next = null,
 prev = null;

    //是否Finalize
    private boolean hasBeenFinalized() {
 return (next == this);
    }

    private void add() {
 synchronized (lock) {
     if (unfinalized != null) {
     //如果unfinalized不为null将当前对象加到unfinalized前 
  this.next = unfinalized;
  unfinalized.prev = this;
     }
    
     //将unfinalized置为当前对象
     unfinalized = this;
 }
    }

    //出队
    private void remove() {
 synchronized (lock) {
     if (unfinalized == this) {
  if (this.next != null) {
      unfinalized = this.next;
  } else {
      unfinalized = this.prev;
  }
     }
     //取出this
     if (this.next != null) {
  this.next.prev = this.prev;
     }
     if (this.prev != null) {
  this.prev.next = this.next;
     }
    
     //将当前对象的next,prev都置成当前对象
     this.next = this;
     this.prev = this;
 }
    }

    //finalizee为referent
    private Finalizer(Object finalizee) {
 super(finalizee, queue);
 add();
    }

    //由虚拟机调用
    static void register(Object finalizee) {
 //队列为static的,所以构造的国政直接加入到对列中
    new Finalizer(finalizee);
    }

    //调用封装对象的finalize方法
    private void runFinalizer() {
 synchronized (this) {
     if (hasBeenFinalized()) return;
     remove();
 }
 try {
  //读取当前对象封装的将引用对象
     Object finalizee = this.get();
     if (finalizee != null) {
     //调用封装对象的finalize方法
  invokeFinalizeMethod(finalizee);
  
  finalizee = null;
     }
 } catch (Throwable x) { }
 super.clear();
    }

    private static void forkSecondaryFinalizer(final Runnable proc) {
 PrivilegedAction pa = new PrivilegedAction() {
     public Object run() {
  ThreadGroup tg = Thread.currentThread().getThreadGroup();
  for (ThreadGroup tgn = tg;
       tgn != null;
       tg = tgn, tgn = tg.getParent());
  Thread sft = new Thread(tg, proc, "Secondary finalizer");
  sft.start();
  try {
      sft.join();
  } catch (InterruptedException x) {
      /* Ignore */
  }
  return null;
     }};
 AccessController.doPrivileged(pa);
    }

    // 由Runtime.runFinalization()方法来调用
    static void runFinalization() {
 forkSecondaryFinalizer(new Runnable() {
     public void run() {
  for (;;) {
   //出队
      Finalizer f = (Finalizer)queue.poll();
      if (f == null) break;
      //调用封装对象的finalize方法
      f.runFinalizer();
  }
     }
 });
    }

    //由java.lang.Shutdown调用
    //调用unfinalized代表的列表的所有对象的强引用的finalize方法
    static void runAllFinalizers() {
 forkSecondaryFinalizer(new Runnable() {
     public void run() {
  for (;;) {
      Finalizer f;
      synchronized (lock) {
   f = unfinalized;
   if (f == null) break;
   unfinalized = f.next;
      }
      f.runFinalizer();
  }}});
    }

    //一个继承自线程的内部类
    private static class FinalizerThread extends Thread {
 FinalizerThread(ThreadGroup g) {
     super(g, "Finalizer");
 }
 public void run() {
     for (;;) {//反复调用队列的remvoe方法得到对象,并调用相应的runFinalizer方法
  try {
      Finalizer f = (Finalizer)queue.remove();
      f.runFinalizer();
  } catch (InterruptedException x) {
      continue;
  }
     }
 }
    }

    static {
     //得到当前线程组
        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        //得到System线程组
        for (ThreadGroup tgn = tg;
             tgn != null;
             tg = tgn, tgn = tg.getParent());
    //启动线程   
 Thread finalizer = new FinalizerThread(tg);
 finalizer.setPriority(Thread.MAX_PRIORITY - 2);
 finalizer.setDaemon(true);
 finalizer.start();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值