ReferenceQueue的处理

java.lang.ref.Reference类中有静态块启动线程(java.lang.ref.Reference.ReferenceHandler)

 static {
    ThreadGroup tg = Thread.currentThread().getThreadGroup();
    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();
}

线程死循环去java.lang.ref.Reference.pending的值(等待队列的列表引用。收集器将引用添加到此列表)

/* 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 (;;) {

            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 q = r.queue;
            if (q != ReferenceQueue.NULL) q.enqueue(r);
        }
    }
}

如果有则丢进队列(java.lang.ref.ReferenceQueue),应用代码调用java.lang.ref.ReferenceQueue.poll()获取引用对象进行处理

/**
 * Polls this queue to see if a reference object is available.  If one is
 * available without further delay then it is removed from the queue and
 * returned.  Otherwise this method immediately returns null.
 *
 * @return  A reference object, if one was immediately available,
 *          otherwise null
 */
public Reference poll() {
    if (head == null)
        return null;
    synchronized (lock) {
        return reallyPoll();
    }
}

private Reference reallyPoll() {       /* Must hold lock */
    if (head != null) {
        Reference r = head;
        head = (r.next == r) ? null : r.next;
        r.queue = NULL;
        r.next = r;
        queueLength--;
        if (r instanceof FinalReference) {
            sun.misc.VM.addFinalRefCount(-1);
        }
        return r;
    }
    return null;
}

使用案例

/**
* 作者:赵北云
* 链接:https://www.zhihu.com/question/35250439/answer/62942987
* 来源:知乎
* 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class ReferenceQueueExample {
    public static void main(String[] args) {// -Xmx32m
        List list = new ArrayList<>();
        // 这个没有加队列 所以会爆
//      for (int i = 0; i < 32 * 1024; i++) {
//          list.add(new FooWeakReference(i));
//      }

        // 这个加咧 所以不会爆
        ReferenceQueue queue = new ReferenceQueue<>();
        FooWeakReference ref = null;
        for (int i = 0; i < 32 * 1024; i++) {
            list.add(new FooWeakReference(i, queue));
            System.out.println(i + ";begin");
            while ((ref = (FooWeakReference) queue.poll()) != null) {
                ref.clean();
                System.out.println(i + ";ref.clean()");
            }
            System.out.println(i + ";end");
        }
    }
}

class FooWeakReference extends WeakReference {
    public FooWeakReference(Integer referent) {
        super(referent);
    }

    public FooWeakReference(Integer referent, ReferenceQueue q) {
        super(referent, q);
    }

    public void clean() {
        this.buffer = null;
    }

    byte[] buffer = new byte[1024];
}

你可能感兴趣的:(ReferenceQueue的处理)