- Reference提供了一些引用的基本方法以及靜態代碼塊最高優先級啓動ReferenceHandler線程
Reference提供了一些引用的基本方法以及靜態代碼塊最高優先級啓動ReferenceHandler線程
- package xxx;
- /**
- * Abstract base class for reference objects. This class defines the
- * operations common to all reference objects. Because reference objects are
- * implemented in close cooperation with the garbage collector, this class may
- * not be subclassed directly.
- * 引用對象的抽象基類。這個類定義了所有引用對象的通用行爲。
- * 因爲引用對象是通過與垃圾回收期密切合作來實現的,所以不能直接爲此類創建子類.
- *
- *
- * @version 1.43, 04/10/06
- * @author Mark Reinhold
- * @since 1.2
- */
- public abstract class Reference<T> {
- /* A Reference instance is in one of four possible internal states:
- * 一種引用實例是可能是四種內部狀態之一:
- * Active: Subject to special treatment by the garbage collector. Some
- * time after the collector detects that the reachability of the
- * referent has changed to the appropriate state, it changes the
- * instance's state to either Pending or Inactive, depending upon
- * whether or not the instance was registered with a queue when it was
- * created. In the former case it also adds the instance to the
- * pending-Reference list. Newly-created instances are Active.
- * 激活:垃圾回收器特別處理的主題。有時候在回收器檢測到被引用(對象)的可達性被改變成適當
- * 的狀態,它會把實例的狀態改變成等待狀態或者未激活狀態,這取決於實例是否被一個隊列註冊當
- * 它被創建。在前一種情況下(等待狀態),它也往等待-引用集合增加實例。
- *
- *
- * Pending: An element of the pending-Reference list, waiting to be
- * enqueued by the Reference-handler thread. Unregistered instances
- * are never in this state.
- * 等待:一個等待-引用集合裏的元素,等待被引用處理線程放入隊列中。
- * 未註冊的實例永遠不會在這個狀態
- *
- * Enqueued: An element of the queue with which the instance was
- * registered when it was created. When an instance is removed from
- * its ReferenceQueue, it is made Inactive. Unregistered instances are
- * never in this state.
- * 入隊:實例被創建的時候被登記註冊成一個隊列的元素。當一個實例從引用隊列中刪除,它變成非激活狀態。
- * 未註冊的實例永遠不會在這個狀態。
- *
- * Inactive: Nothing more to do. Once an instance becomes Inactive its
- * state will never change again.
- * 非激活:不會再做什麼。一旦一個實例成爲非激活的,它的狀態永遠不會被改變。
- *
- *
- * The state is encoded in the queue and next fields as follows:
- * 狀態在隊列裏被處理並且每個狀態所表現的屬性如下:
- *
- *
- * Active: queue = ReferenceQueue with which instance is registered, or
- * ReferenceQueue.NULL if it was not registered with a queue; next =
- * null.
- * 激活:queue=引用隊列時候,實例被它註冊,
- * 或者實例不被註冊,當queue=ReferenceQueue.NULL時候;
- * next=null.
- *
- * Pending: queue = ReferenceQueue with which instance is registered;
- * next = Following instance in queue, or this if at end of list.
- * 等待:queue=引用隊列時候,實例被它註冊,
- * next=剩下的queue隊列裏面的實例,或者=this,如果this是隊列的最後一個。
- *
- * Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
- * in queue, or this if at end of list.
- * 入隊:queue=ReferenceQueue.ENQUEUED
- * next=剩下的queue隊列裏面的實例,或者=this,如果this是隊列的最後一個
- *
- *
- * Inactive: queue = ReferenceQueue.NULL; next = this.
- * 終止:隊列=ReferenceQueue.NULL next=this
- *
- * With this scheme the collector need only examine the next field in order
- * to determine whether a Reference instance requires special treatment: If
- * the next field is null then the instance is active; if it is non-null,
- * then the collector should treat the instance normally.
- *
- *
- *
- * To ensure that concurrent collector can discover active Reference
- * objects without interfering with application threads that may apply
- * the enqueue() method to those objects, collectors should link
- * discovered objects through the discovered field.
- */
- private T referent; /* Treated specially by GC */ //被GC引用的對象
- ReferenceQueue<? super T> queue;//引用隊列
- Reference next;//下個引用
- transient private Reference<T> discovered; /* used by VM *///被VM引用的瞬態對象
- /* Object used to synchronize with the garbage collector. The collector
- * must acquire this lock at the beginning of each collection cycle. It is
- * therefore critical that any code holding this lock complete as quickly
- * as possible, allocate no new objects, and avoid calling user code.
- * GC線程在回收的時候的鎖
- * 對象被用來和GC同步。GC必須獲得鎖在每個回收的生命週期。
- * 更關鍵的是任何持有鎖的代碼儘可能快的執行完,沒有分配新的對象,並避免使用使用者的代碼。
- *
- */
- static private class Lock { };
- private static Lock lock = new Lock();
- /* List of References waiting to be enqueued. The collector adds
- * References to this list, while the Reference-handler thread removes
- * them. This list is protected by the above lock object.
- * 排隊的引用集合。當處理引用的線程刪除引用時候,收集器添加引用到這個集合。
- * 這個集合受上面的對象鎖保護。
- */
- private static Reference pending = null;
- /* High-priority thread to enqueue pending References
- * 處理排隊等待的引用的高優先的線程
- */
- private static class ReferenceHandler extends Thread {
- ReferenceHandler(ThreadGroup g, String name) {
- super(g, name);
- }
- public void run() {
- for (;;) {
- /*
- * 給pending賦值
- * 如果pending.next=pending,pending=null;否則pending=pengding.next,最後把pending.next=pending
- * 下次執行線程裏的代碼時候pending=null了,再下次執行同步代碼塊就線程阻塞了
- *
- * 如果pending屬性爲空,釋放鎖的對象監視器,阻塞當前線程
- * */
- Reference r;
- synchronized (lock) {
- if (pending != null) {
- r = pending;
- Reference rn = r.next;
- pending = (rn == r) ? null : rn;
- r.next = r;
- } else {
- try {
- lock.wait();
- } catch (InterruptedException x) { }
- continue;
- }
- }
- // Fast path for cleaners
- if (r instanceof Cleaner) {
- ((Cleaner)r).clean();
- continue;
- }
- /*
- * ReferenceQueue.NULL的實現:
- * private static class Null extends ReferenceQueue {
- * boolean enqueue(Reference r) {
- * return false;
- }
- }
- * 如果Q不爲空,把引用放入Queue
- * 在剛創建一個引用,第二個參數沒放Queue時候,爲空。
- * */
- 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");
- /* If there were a special system-only priority greater than
- * MAX_PRIORITY, it would be used here
- */
- handler.setPriority(Thread.MAX_PRIORITY);//設置最高優先級
- handler.setDaemon(true);//標記守護線程或用戶線程
- handler.start();//守護線程啓動
- }
- /* -- Referent accessor and setters -- */
- /**
- * Returns this reference object's referent. If this reference object has
- * been cleared, either by the program or by the garbage collector, then
- * this method returns <code>null</code>.
- *
- * @return The object to which this reference refers, or
- * <code>null</code> if this reference object has been cleared
- * 獲得引用對象
- */
- public T get() {
- return this.referent;
- }
- /**
- * Clears this reference object. Invoking this method will not cause this
- * object to be enqueued.
- *
- * <p> This method is invoked only by Java code; when the garbage collector
- * clears references it does so directly, without invoking this method.
- * 清除引用對象
- */
- public void clear() {
- this.referent = null;
- }
- /* -- Queue operations -- */
- /**
- * Tells whether or not this reference object has been enqueued, either by
- * the program or by the garbage collector. If this reference object was
- * not registered with a queue when it was created, then this method will
- * always return <code>false</code>.
- *
- * @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
- 是否處於等待狀態
- 判斷條件:隊列不爲空,
- 它的next屬性不爲空。
- 剛初始化一個Reference時候,next屬性肯定是空的,因此肯定不處於等待狀態
- */
- synchronized (this) {
- return (this.queue != ReferenceQueue.NULL) && (this.next != null);
- }
- }
- /**
- * Adds this reference object to the queue with which it is registered,
- * if any.
- *
- * <p> This method is invoked only by Java code; when the garbage collector
- * enqueues references it does so directly, without invoking this method.
- *
- * @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(T referent) {
- this(referent, null);
- }
- Reference(T referent, ReferenceQueue<? super T> queue) {
- this.referent = referent;
- this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
- }
- }