一、总结
1.jkd 1.8.0
2.作用
该队列作为引用中的一员,可以和上述三种引用类型组合使用,该队列的作用是:创建Reference时,将Queue注册到Reference中,当该Reference所引用的对象被垃圾收集器回收时,会将该Reference放到该队列中,相当于一种通知机制。
二、源码分析
/** * Reference queues, to which registered reference objects are appended by the * garbage collector after the appropriate reachability changes are detected. * * @author Mark Reinhold * @since 1.2 */ public class ReferenceQueue{ }
- Reference queues,在适当的时候检测到对象的可达性发生改变后,垃圾回收器就将已注册的引用对象添加到此队列中。
/** * Constructs a new reference-object queue. */ public ReferenceQueue() { }
- 构造方法,需指定泛型
// 私有内部静态类 Null ,继承 ReferenceQueue ,并覆盖实现父类中的方法 enqueue private static class Nullextends ReferenceQueue{ boolean enqueue(Reference extends S> r) { return false; } } // Reference 对象出队列标识,即 Reference 状态,由 Enqueued 变为 Inactive static ReferenceQueue
- 出队、入队标识,队列指的是 Reference 构造方法中 ReferenceQueue 参数
static private class Lock { }; private Lock lock = new Lock();
- 锁:类对象锁
private volatile Reference extends T> head = null;
- 列表头部
- 作用:出队、入队操作时,作为临时变量保存数据
private long queueLength = 0;
- 队列中元素的个数
- 类中的属性,实例对象私有,Reference 构造方法需要传入 ReferenceQueue 的实例对象,此属性指的是传入对象的队列中的对象的数量
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; // 检查需要入队的 Reference 对象,对象的 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; } }
- 添加入队标识
- 新加入的元素在队列头部
@SuppressWarnings("unchecked")
private Reference extends T> reallyPoll() { /* Must hold lock */
Reference extends T> r = head;
if (r != null) {
// r.next == r 仅有一个元素
head = (r.next == r) ?
null :
r.next; // Unchecked due to the next field having a raw type in Reference
r.queue = NULL;
// 出队元素的next 指向自己
r.next = r;
queueLength--;
if (r instanceof FinalReference) {
sun.misc.VM.addFinalRefCount(-1);
}
return r;
}
return null;
}
/**
* 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 extends T> poll() {
if (head == null)
return null;
synchronized (lock) {
return reallyPoll();
}
}
- 添加出队标识
- 从头部开始出队,先入后出
/** * Removes the next reference object in this queue, blocking until either * one becomes available or the given timeout period expires. * *This method does not offer real-time guarantees: It schedules the * timeout as if by invoking the {@link Object#wait(long)} method. * * @param timeout If positive, block for up to
timeout
* milliseconds while waiting for a reference to be * added to this queue. If zero, block indefinitely. * * @return A reference object, if one was available within the specified * timeout period, otherwisenull
* * @throws IllegalArgumentException * If the value of the timeout argument is negative * * @throws InterruptedException * If the timeout wait is interrupted */ public Reference extends T> remove(long timeout) throws IllegalArgumentException, InterruptedException { if (timeout < 0) { throw new IllegalArgumentException("Negative timeout value"); } synchronized (lock) { Reference extends T> r = reallyPoll(); if (r != null) return r; long start = (timeout == 0) ? 0 : System.nanoTime(); for (;;) { lock.wait(timeout); r = reallyPoll(); if (r != null) return r; if (timeout != 0) { long end = System.nanoTime(); timeout -= (end - start) / 1000_000; if (timeout <= 0) return null; start = end; } } } } /** * Removes the next reference object in this queue, blocking until one * becomes available. * * @return A reference object, blocking until one becomes available * @throws InterruptedException If the wait is interrupted */ public Reference extends T> remove() throws InterruptedException { return remove(0); } }
- 删除队列中的下一个引用对象,阻塞队列直到一个引用对象变为可达
博文参考:
Java Reference 源码分析