java.lang.ref.Reference

Java代碼 複製代碼 收藏代碼
  1. Reference提供了一些引用的基本方法以及靜態代碼塊最高優先級啓動ReferenceHandler線程  
Reference提供了一些引用的基本方法以及靜態代碼塊最高優先級啓動ReferenceHandler線程
Java代碼 複製代碼 收藏代碼
  1. package xxx;   
  2.     
  3. /**  
  4.  * Abstract base class for reference objects.  This class defines the  
  5.  * operations common to all reference objects. Because reference objects are  
  6.  * implemented in close cooperation with the garbage collector, this class may  
  7.  * not be subclassed directly.  
  8.  * 引用對象的抽象基類。這個類定義了所有引用對象的通用行爲。  
  9.  * 因爲引用對象是通過與垃圾回收期密切合作來實現的,所以不能直接爲此類創建子類.  
  10.  *   
  11.  *  
  12.  * @version  1.43, 04/10/06  
  13.  * @author   Mark Reinhold  
  14.  * @since    1.2  
  15.  */  
  16. public abstract class Reference<T> {   
  17.     /* A Reference instance is in one of four possible internal states:  
  18.      * 一種引用實例是可能是四種內部狀態之一:  
  19.      *    Active: Subject to special treatment by the garbage collector.  Some  
  20.      *    time after the collector detects that the reachability of the  
  21.      *    referent has changed to the appropriate state, it changes the  
  22.      *    instance's state to either Pending or Inactive, depending upon  
  23.      *    whether or not the instance was registered with a queue when it was  
  24.      *    created.  In the former case it also adds the instance to the  
  25.      *    pending-Reference list.  Newly-created instances are Active.  
  26.      *    激活:垃圾回收器特別處理的主題。有時候在回收器檢測到被引用(對象)的可達性被改變成適當  
  27.      *    的狀態,它會把實例的狀態改變成等待狀態或者未激活狀態,這取決於實例是否被一個隊列註冊當  
  28.      *    它被創建。在前一種情況下(等待狀態),它也往等待-引用集合增加實例。  
  29.      *  
  30.      *  
  31.      *    Pending: An element of the pending-Reference list, waiting to be  
  32.      *    enqueued by the Reference-handler thread.  Unregistered instances  
  33.      *    are never in this state.  
  34.      *    等待:一個等待-引用集合裏的元素,等待被引用處理線程放入隊列中。  
  35.      *    未註冊的實例永遠不會在這個狀態  
  36.      *  
  37.      *    Enqueued: An element of the queue with which the instance was  
  38.      *    registered when it was created.  When an instance is removed from  
  39.      *    its ReferenceQueue, it is made Inactive.  Unregistered instances are  
  40.      *    never in this state.  
  41.      *    入隊:實例被創建的時候被登記註冊成一個隊列的元素。當一個實例從引用隊列中刪除,它變成非激活狀態。  
  42.      *    未註冊的實例永遠不會在這個狀態。        
  43.      *  
  44.      *    Inactive: Nothing more to do.  Once an instance becomes Inactive its  
  45.      *    state will never change again.  
  46.      *    非激活:不會再做什麼。一旦一個實例成爲非激活的,它的狀態永遠不會被改變。  
  47.      *      
  48.      *  
  49.      * The state is encoded in the queue and next fields as follows:  
  50.      * 狀態在隊列裏被處理並且每個狀態所表現的屬性如下:  
  51.      *   
  52.      *  
  53.      *    Active: queue = ReferenceQueue with which instance is registered, or  
  54.      *    ReferenceQueue.NULL if it was not registered with a queue; next =  
  55.      *    null.  
  56.      *    激活:queue=引用隊列時候,實例被它註冊,  
  57.      *    或者實例不被註冊,當queue=ReferenceQueue.NULL時候;  
  58.      *    next=null.  
  59.      *  
  60.      *    Pending: queue = ReferenceQueue with which instance is registered;  
  61.      *    next = Following instance in queue, or this if at end of list.  
  62.      *    等待:queue=引用隊列時候,實例被它註冊,  
  63.      *    next=剩下的queue隊列裏面的實例,或者=this,如果this是隊列的最後一個。  
  64.      *  
  65.      *    Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance  
  66.      *    in queue, or this if at end of list.  
  67.      *    入隊:queue=ReferenceQueue.ENQUEUED   
  68.      *    next=剩下的queue隊列裏面的實例,或者=this,如果this是隊列的最後一個  
  69.      *      
  70.      *      
  71.      *    Inactive: queue = ReferenceQueue.NULL; next = this.  
  72.      *    終止:隊列=ReferenceQueue.NULL next=this  
  73.      *  
  74.      * With this scheme the collector need only examine the next field in order  
  75.      * to determine whether a Reference instance requires special treatment: If  
  76.      * the next field is null then the instance is active; if it is non-null,  
  77.      * then the collector should treat the instance normally.  
  78.      *   
  79.      *   
  80.      *   
  81.      * To ensure that concurrent collector can discover active Reference   
  82.      * objects without interfering with application threads that may apply   
  83.      * the enqueue() method to those objects, collectors should link   
  84.      * discovered objects through the discovered field.  
  85.      */  
  86.     private T referent;  /* Treated specially by GC */ //被GC引用的對象   
  87.     ReferenceQueue<? super T> queue;//引用隊列   
  88.     Reference next;//下個引用   
  89.     transient private Reference<T> discovered;  /* used by VM *///被VM引用的瞬態對象   
  90.   
  91.     /* Object used to synchronize with the garbage collector.  The collector  
  92.      * must acquire this lock at the beginning of each collection cycle.  It is  
  93.      * therefore critical that any code holding this lock complete as quickly  
  94.      * as possible, allocate no new objects, and avoid calling user code.  
  95.      * GC線程在回收的時候的鎖  
  96.      * 對象被用來和GC同步。GC必須獲得鎖在每個回收的生命週期。  
  97.      * 更關鍵的是任何持有鎖的代碼儘可能快的執行完,沒有分配新的對象,並避免使用使用者的代碼。  
  98.      *   
  99.      */  
  100.     static private class Lock { };   
  101.     private static Lock lock = new Lock();   
  102.   
  103.     /* List of References waiting to be enqueued.  The collector adds  
  104.      * References to this list, while the Reference-handler thread removes  
  105.      * them.  This list is protected by the above lock object.  
  106.      * 排隊的引用集合。當處理引用的線程刪除引用時候,收集器添加引用到這個集合。  
  107.      * 這個集合受上面的對象鎖保護。  
  108.      */  
  109.     private static Reference pending = null;   
  110.     /* High-priority thread to enqueue pending References  
  111.      * 處理排隊等待的引用的高優先的線程  
  112.      */  
  113.     private static class ReferenceHandler extends Thread {   
  114.         ReferenceHandler(ThreadGroup g, String name) {   
  115.             super(g, name);   
  116.             }   
  117.         public void run() {   
  118.             for (;;) {   
  119.                 /*  
  120.                  * 給pending賦值  
  121.                  * 如果pending.next=pending,pending=null;否則pending=pengding.next,最後把pending.next=pending  
  122.                  * 下次執行線程裏的代碼時候pending=null了,再下次執行同步代碼塊就線程阻塞了  
  123.                  *   
  124.                  * 如果pending屬性爲空,釋放鎖的對象監視器,阻塞當前線程  
  125.                  * */    
  126.                 Reference r;   
  127.                 synchronized (lock) {   
  128.                     if (pending != null) {   
  129.                         r = pending;   
  130.                         Reference rn = r.next;   
  131.                         pending = (rn == r) ? null : rn;   
  132.                         r.next = r;   
  133.                     } else {   
  134.                         try {   
  135.                             lock.wait();   
  136.                         } catch (InterruptedException x) { }   
  137.                         continue;   
  138.                     }   
  139.                 }   
  140.                 // Fast path for cleaners    
  141.                 if (r instanceof Cleaner) {   
  142.                     ((Cleaner)r).clean();   
  143.                     continue;   
  144.                 }   
  145.                 /*  
  146.                  *  ReferenceQueue.NULL的實現:   
  147.                  *  private static class Null extends ReferenceQueue {  
  148.                  * boolean enqueue(Reference r) {  
  149.                  * return false;  
  150.             }  
  151.         }  
  152.                  * 如果Q不爲空,把引用放入Queue  
  153.                  * 在剛創建一個引用,第二個參數沒放Queue時候,爲空。  
  154.                  * */  
  155.                 ReferenceQueue q = r.queue;   
  156.                 if (q != ReferenceQueue.NULL) q.enqueue(r);   
  157.             }   
  158.         }   
  159.     }   
  160.         static {   
  161.             //取得當前線程組   
  162.             ThreadGroup tg = Thread.currentThread().getThreadGroup();   
  163.             //取得最上層的System線程組   
  164.             for (ThreadGroup tgn = tg;   
  165.             tgn != null;   
  166.             tg = tgn, tgn = tg.getParent());   
  167.             //創建線程對象   
  168.             Thread handler = new ReferenceHandler(tg, "Reference Handler");   
  169.             /* If there were a special system-only priority greater than  
  170.              * MAX_PRIORITY, it would be used here  
  171.              */  
  172.             handler.setPriority(Thread.MAX_PRIORITY);//設置最高優先級   
  173.             handler.setDaemon(true);//標記守護線程或用戶線程   
  174.             handler.start();//守護線程啓動   
  175.         }   
  176.   
  177.         /* -- Referent accessor and setters -- */  
  178.         /**  
  179.          * Returns this reference object's referent.  If this reference object has  
  180.          * been cleared, either by the program or by the garbage collector, then  
  181.          * this method returns <code>null</code>.  
  182.          *  
  183.          * @return  The object to which this reference refers, or  
  184.          *   <code>null</code> if this reference object has been cleared  
  185.          * 獲得引用對象  
  186.          */  
  187.         public T get() {   
  188.             return this.referent;   
  189.         }   
  190.         /**  
  191.          * Clears this reference object.  Invoking this method will not cause this  
  192.          * object to be enqueued.  
  193.          *  
  194.          * <p> This method is invoked only by Java code; when the garbage collector  
  195.          * clears references it does so directly, without invoking this method.  
  196.          * 清除引用對象  
  197.          */  
  198.         public void clear() {   
  199.             this.referent = null;   
  200.         }   
  201.   
  202.         /* -- Queue operations -- */  
  203.         /**  
  204.          * Tells whether or not this reference object has been enqueued, either by  
  205.          * the program or by the garbage collector.  If this reference object was  
  206.          * not registered with a queue when it was created, then this method will  
  207.          * always return <code>false</code>.  
  208.          *  
  209.          * @return  <code>true</code> if and only if this reference object has  
  210.          *   been enqueued  
  211.          */  
  212.         public boolean isEnqueued() {   
  213.             /* In terms of the internal states, this predicate actually tests  
  214.             whether the instance is either Pending or Enqueued   
  215.             是否處於等待狀態  
  216.             判斷條件:隊列不爲空,  
  217.             它的next屬性不爲空。  
  218.             剛初始化一個Reference時候,next屬性肯定是空的,因此肯定不處於等待狀態  
  219.              */  
  220.             synchronized (this) {   
  221.                 return (this.queue != ReferenceQueue.NULL) && (this.next != null);   
  222.                 }   
  223.             }   
  224.         /**  
  225.          * Adds this reference object to the queue with which it is registered,  
  226.          * if any.  
  227.          *  
  228.          * <p> This method is invoked only by Java code; when the garbage collector  
  229.          * enqueues references it does so directly, without invoking this method.  
  230.          *  
  231.          * @return  <code>true</code> if this reference object was successfully  
  232.          *   enqueued; <code>false</code> if it was already enqueued or if  
  233.         *   it was not registered with a queue when it was created  
  234.         * 加入等待隊列  
  235.             */  
  236.         public boolean enqueue() {   
  237.             return this.queue.enqueue(this);   
  238.         }   
  239.   
  240.         /* -- Constructors -- */  
  241.         Reference(T referent) {   
  242.             this(referent, null);   
  243.         }   
  244.         Reference(T referent, ReferenceQueue<? super T> queue) {   
  245.             this.referent = referent;   
  246.             this.queue = (queue == null) ? ReferenceQueue.NULL : queue;   
  247.         }   
  248.     }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章