ReferenceQueue

[align=center][size=large]ReferenceQueue[/size][/align]

一、总结

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<T> {

}


[list]
[*]Reference queues,在适当的时候检测到对象的可达性发生改变后,垃圾回收器就将已注册的引用对象添加到此队列中。
[/list]


/**
* Constructs a new reference-object queue.
*/
public ReferenceQueue() { }


[list]
[*]构造方法,需指定泛型
[/list]


// 私有内部静态类 Null ,继承 ReferenceQueue ,并覆盖实现父类中的方法 enqueue
private static class Null<S> extends ReferenceQueue<S> {
boolean enqueue(Reference<? extends S> r) {
return false;
}
}
// Reference 对象出队列标识,即 Reference 状态,由 Enqueued 变为 Inactive
static ReferenceQueue<Object> NULL = new Null<>();
// Reference 对象入队列标识,即 Reference 状态,由 Pending 变为 Enqueued
static ReferenceQueue<Object> ENQUEUED = new Null<>();


[list]
[*]出队、入队标识,队列指的是 Reference 构造方法中 ReferenceQueue 参数
[/list]


static private class Lock { };
private Lock lock = new Lock();


[list]
[*]锁:类对象锁
[/list]


private volatile Reference<? extends T> head = null;


[list]
[*]列表头部
[*]作用:出队、入队操作时,作为临时变量保存数据
[/list]


private long queueLength = 0;


[list]
[*]队列中元素的个数
[*]类中的属性,实例对象私有,Reference 构造方法需要传入 ReferenceQueue 的实例对象,此属性指的是传入对象的队列中的对象的数量
[/list]


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;
}
}



[list]
[*]添加入队标识
[*]新加入的元素在队列头部
[/list]



@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 <tt>null</tt>.
*
* @return A reference object, if one was immediately available,
* otherwise <code>null</code>
*/
public Reference<? extends T> poll() {
if (head == null)
return null;
synchronized (lock) {
return reallyPoll();
}
}



[list]
[*]添加出队标识
[*]从头部开始出队,先入后出
[/list]



/**
* Removes the next reference object in this queue, blocking until either
* one becomes available or the given timeout period expires.
*
* <p> 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 <code>timeout</code>
* 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, otherwise <code>null</code>
*
* @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);
}

}




[list]
[*]删除队列中的下一个引用对象,阻塞队列直到一个引用对象变为可达
[/list]
博文参考:
[url=https://www.cnblogs.com/jabnih/p/6580665.html]Java Reference 源码分析[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值