java.lang.ref.Reference

來源:互聯網
上載者:User

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;
 }
    }

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.