java.lang.ref.Reference

package java.lang.ref;

import sun.misc.Cleaner;


/**
 * 一个抽象类,是所有reference类的超类,此类不能直接集成,它与垃圾回收有很紧密的关系
 * 用来表示弱引用(weak reference),可以强一个强引用的对象封装,并使用get()方法重新获得此对象
 * 在此类中的静态块中会启动一个线程,用来轮巡pending对象,使其入队
 *
 * comment by liqiang
 *
 * @author   Mark Reinhold
 *
 */

public abstract class Reference {

    /* 一个引用对象有四个状态:
     *
     * Active(有效):此对象有效,他被GC特殊处理,当此对象的可触及性发生变化时(对此对象的引用), 它将改变成挂起或无效状态
     * 它的对象状态 queue: 注册的ReferenceQueue对象(注册了队列), ReferenceQueue.NULL(没有注册队列)
     *            next: null
     *
     * Pending(挂起):元素等待入队,没有注册队列的元素不能为此状态
     * 它的对象状态 queue: 注册的ReferenceQueue对象(注册了队列), ReferenceQueue.NULL(没有注册队列)
     *      next: 队列中的下一个对象 如果是队列中的最后一个对象 next=this
     *
     * Enqueued(入队):元素已经入队,没有注册队列的元素不能为此状态,当元素从队列中remove出来的时候,元素状态变为Inactive
     * 它的对象状态 queue: ReferenceQueue.ENQUEUED
     *            next: 队列中的下一个对象 如果是队列中的最后一个对象 next=this
     *
     * Inactive(无效):表示此引用不可用,元素为此状态时它的状态不可改变
     * 它的对象状态 queue = ReferenceQueue.NULL;
     *            next = this.
     *
     * GC判断next状态,如果next=null则为Active状态,否则需要对它进行特殊处理
     *
     */

 //此引用对象封装的对象
    private Object referent;
    //引用对象的队列
    ReferenceQueue queue;
    //下一个元素
    Reference next;
   
    //虚拟机使用
    transient private Reference discovered;

    //一个静态内部类 表示锁
    static private class Lock { };
    private static Lock lock = new Lock();


    //等待入队的元素列
    private static Reference pending = null;

    //此线程在类装载时启动,用来将pending的元素入队
    private static class ReferenceHandler extends Thread {

 ReferenceHandler(ThreadGroup g, String name) {
     super(g, name);
 }

 public void run() {
     for (;;) {

  Reference r;
  //lock是一个静态对象,线程也是在static块中启动的,所以所有的
  //此refence类都只有一个线程,和锁,此锁的目的是保护此对象中的同步区域块内的数据
  synchronized (lock) {
      if (pending != null) {
      //如果pending不为null取出此对象
   r = pending;
   Reference rn = r.next;
   //将原pending的下一个元素,赋给当前的pending
   //如果原pending的下一个元素为自己,则当前pending=null
   pending = (rn == r) ? null : rn;
   r.next = r;
      } else {
   try {
    //如果没有pending对象则阻塞线程
       lock.wait();
   } catch (InterruptedException x) { }
   continue;
      }
  }

  // Fast path for cleaners
  if (r instanceof Cleaner) {
      ((Cleaner)r).clean();
      continue;
  }

  ReferenceQueue q = r.queue;
  //如果当前元素已经注册到队列则入队
  if (q != ReferenceQueue.NULL) q.enqueue(r);
     }
 }
    }

    static {
    //取得当前线程组
 ThreadGroup tg = Thread.currentThread().getThreadGroup();
 //取得最上层的System线程组
 for (ThreadGroup tgn = tg;
      tgn != null;
      tg = tgn, tgn = tg.getParent());
 //生成线程对象
 Thread handler = new ReferenceHandler(tg, "Reference Handler");
 
 //启动线程
 handler.setPriority(Thread.MAX_PRIORITY);
 handler.setDaemon(true);
 handler.start();
    }


    /* -- Referent accessor and setters -- */

    /**
     *
     * 返回此应用对象封装的强引用对象, 如果强引用对象被垃圾回收,或程序调用了此对象的clear方法
     * 则返回的对象为null
     *
     * @return  The object to which this reference refers, or
     *   <code>null</code> if this reference object has been cleared
     */
    public Object get() {
 return this.referent;
    }

    /**
     *
     * 清空它的referent对象,此方法不会将对象入队
     */
    public void clear() {
 this.referent = null;
    }


    /* -- Queue operations -- */

    /**
     *
     * 判断此对象是否入队,就是判断他的内部状态是否是Pending或Enqueued
     *
     * @return  <code>true</code> if and only if this reference object has
     *   been enqueued
     */
    public boolean isEnqueued() {
 /* In terms of the internal states, this predicate actually tests
    whether the instance is either Pending or Enqueued */
 synchronized (this) {
     return (this.queue != ReferenceQueue.NULL) && (this.next != null);
 }
    }

    /**
     * Adds this reference object to the queue with which it is registered,
     * if any.
     *
     * 入队操作
     *
     * @return ture: 表示入队成功 false: 表示它已经入队或没有注册队列
     * @return  <code>true</code> if this reference object was successfully
     *   enqueued; <code>false</code> if it was already enqueued or if
     *   it was not registered with a queue when it was created
     */
    public boolean enqueue() {
 return this.queue.enqueue(this);
    }


    /* -- Constructors -- */

    //构造函数
    Reference(Object referent) {
 this(referent, null);
    }

    //构造函数
    Reference(Object referent, ReferenceQueue queue) {
 this.referent = referent;
 if (referent == null) {
  //如果强引用对象为null则标志此引用对象为 inactive
     /* Immediately make this instance inactive */
     this.queue = ReferenceQueue.NULL;
     this.next = this;
 } else {
  //初始queue对象,如果不为null直接赋值,为null则赋给ReferenceQueue.NULL
     this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
     //next = null 表示Active状态
     this.next = null;
 }
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值