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