欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

null); } Ref 图纸加密 erence(T referent

点击: 次  来源:宝鼎软件 时间:2017-08-12

原文出处: 林玲 投稿

ReferenceQueue

引用行列,在检测到适当的可达到性变动后,垃圾接纳器将已注册的引用工具添加到该行列中。

实现了一个行列的入队(enqueue)和出队(poll尚有remove)操纵,内部元素就是泛型的Reference,而且Queue的实现,是由Reference自身的链表布局( 单向轮回链表 )所实现的。

ReferenceQueue名义上是一个行列,但实际内部并非有实际的存储布局,它的存储是依赖于内部节点之间的干系来表达。可以领略为queue是一个雷同于链表的布局,这里的节点其实就是reference自己。可以领略为queue为一个链表的容器,其本身仅存储当前的head节点,尔后头的节点由每个reference节点本身通过next来保持即可。

  • 属性
  • head:始终生存当前行列中最新要被处理惩罚的节点,可以认为queue为一个后进先出的行列。当新的节点进入时,采纳以下的逻辑:

    r.next = (head == null) ? r : head;
    head = r;

    然后,在获取的时候,采纳相应的逻辑:

    Reference<? extends T> r = head;
            if (r != null) {
                head = (r.next == r) ?
                    null :
                    r.next; // Unchecked due to the next field having a raw type in Reference
                r.queue = NULL;
                r.next = r;
  • 要领
  • enqueue():待处理惩罚引用入队

    boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
            synchronized (lock) {
                // Check that since getting the lock this reference hasn't already been
                // enqueued (and even then removed)
                ReferenceQueue<?> queue = r.queue;
                if ((queue == NULL) || (queue == ENQUEUED)) {
                    return false;
                }
                assert queue == this;
                r.queue = ENQUEUED;
                r.next = (head == null) ? r : head;
                head = r;
                queueLength++;
                if (r instanceof FinalReference) {
                    sun.misc.VM.addFinalRefCount(1);
                }
                lock.notifyAll(); // ①
                return true;
            }
        }

    ① lock.notifyAll(); 通知外部措施之前阻塞在当前行列之上的环境。( 即之前一直没有拿到待处理惩罚的工具,如ReferenceQueue的remove()要领 )

    Reference

    java.lang.ref.Reference 为 软(soft)引用、弱(weak)引用、虚(phantom)引用的父类。

    因为Reference工具和垃圾接纳密切共同实现,软件开发,该类大概不能被直接子类化。
    可以领略为Reference的直接子类都是由jvm定制化处理惩罚的,因此在代码中直接担任于Reference范例没有任何浸染。但可以担任jvm定制的Reference的子类。
    譬喻:Cleaner 担任了 PhantomReference
    public class Cleaner extends PhantomReference<Object>

    结构函数

    其内部提供2个结构函数,一个带queue,一个不带queue。个中queue的意义在于,我们可以在外部对这个queue举办监控。即假如有工具即将被接纳,那么相应的reference工具就会被放到这个queue里。我们拿到reference,就可以再作一些事务。

    而假如不带的话,就只有不绝地轮询reference工具,通过判定内里的get是否返回null( phantomReference工具不能这样作,其get始终返回null,因此它只有带queue的结构函数 )。这两种要领均有相应的利用场景,取决于实际的应用。如weakHashMap中就选择去查询queue的数据,来鉴定是否有工具将被接纳。而ThreadLocalMap,则回收判定get()是否为null来作处理惩罚。

    /* -- Constructors -- */
    
        Reference(T referent) {
            this(referent, null);
        }
    
        Reference(T referent, ReferenceQueue<? super T> queue) {
            this.referent = referent;
            this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
        }

    假如我们在建设一个引用工具时,指定了ReferenceQueue,那么当引用工具指向的工具到达符合的状态(按照引用范例差异而差异)时,GC 会把引用工具自己添加到这个行列中,利便我们处理惩罚它,软件开发,因为“引用工具指向的工具 GC 会自动清理,可是引用工具自己也是工具(是工具就占用必然资源),所以需要我们本身清理。”

    Reference链表布局内部主要的成员有

    ① pending 和 discovered

    /* 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. The
         * list uses the discovered field to link its elements.
         */
        private static Reference<Object> pending = null;
    
        /* When active:   next element in a discovered reference list maintained by GC (or this if last)
         *     pending:   next element in the pending list (or null if last)
         *   otherwise:   NULL
         */
        transient private Reference<T> discovered;  /* used by VM */