package java.lang.ref;
/**
* 引用队列
*
* comment by liqiang
*
* @version 1.20, 01/23/03
* @author Mark Reinhold
* @since 1.2
*/
public class ReferenceQueue {
/**
* 构造函数
*/
public ReferenceQueue() { }
//一个静态内部类,用来生成无队列或已入队标志,此类没有入队的能力
private static class Null extends ReferenceQueue {
boolean enqueue(Reference r) {
return false;
}
}
//表示reference对象没有注册队列
static ReferenceQueue NULL = new Null();
//表示feference对象已经入队
static ReferenceQueue ENQUEUED = new Null();
//一个静态内部类,用来表示锁
static private class Lock { };
private Lock lock = new Lock();
//列表的头
private Reference head = null;
private long queueLength = 0;
//入队操作
boolean enqueue(Reference r) {//由Reference类的enqueue()方法调用
synchronized (r) {
//如果已经入队则返回false
if (r.queue == ENQUEUED) return false;
synchronized (lock) {
r.queue = ENQUEUED;
//如果原来的头元素不空则,此对象的下一个对象为原来的头元素,否则指向自己
r.next = (head == null) ? r : head;
//入队元素为新的头元素
head = r;
//队列长度增长
queueLength++;
lock.notifyAll();
return true;
}
}
}
//出队的操作方法
private Reference reallyPoll() {//此方法调用在lock锁下
if (head != null) {
Reference r = head;
//如果当前头元素的下一元素不空,则当前头元素为原头元素的下一元素
//否则当前头元素为null
head = (r.next == r) ? null : r.next;
//将出队元素的队列标志为空
r.queue = NULL;
//将出队元素的下一元素指向自己
r.next = r;
//队列长度-1
queueLength--;
return r;
}
return null;
}
/**
*
* 元素出队,如果元素有效则返回此元素,否则返回null
*
* @return 出队引用对象如果可用则返回,如果不可用则返回null
*
*/
public Reference poll() {
synchronized (lock) {
return reallyPoll();
}
}
/**
* 元素出队,如果元素有效则返回此元素,否则返回null
*
*
* 元素出队
*
* @param timeout 等待时间
*
* @return A出队引用对象如果可用则返回,如果不可用则返回null
*
*/
public Reference remove(long timeout)
throws IllegalArgumentException, InterruptedException
{
//如果等待时间为负抛出异常
if (timeout < 0) {
throw new IllegalArgumentException("Negative timeout value");
}
synchronized (lock) {
//出队
Reference r = reallyPoll();
//不空则直接返回
if (r != null) return r;
//轮巡
for (;;) {
lock.wait(timeout);
r = reallyPoll();
if (r != null) return r;
if (timeout != 0) return null;
}
}
}
/**
* 返回一个元素对象,如果没有则无限等待
*
*/
public Reference remove() throws InterruptedException {
return remove(0);
}
}