Object obj = new Object(); ReferenceQueue<Object> refQueue = new ReferenceQueue<>(); PhantomReference<Object> phantom = new PhantomReference<Object>(obj, refQueue); ReferenceQueue
ReferenceQueue queue = new ReferenceQueue(); WeakReference reference = new WeakReference(new Object(), queue); System.out.println(reference); System.gc(); Reference reference1 = queue.remove(); System.out.println(reference1);
// 用于保存对象的引用,GC会根据不同Reference来特别对待
private T referent;
// 如果需要通知机制,则保存的对对应的队列
ReferenceQueue<? super T> queue;
/* 这个用于实现一个单向循环链表,用以将保存需要由ReferenceHandler处理的引用 */
Reference next;
static private class Lock { };
// 锁,用于同步pending队列的进队和出队
private static Lock lock = new Lock();
// 此属性保存一个PENDING的队列,配合上述next一起使用
private static Reference pending = null;
// 此线程在静态块中启动,即一旦使用了Reference,则会启动该线程
private static class ReferenceHandler extends Thread {
public void run() {
for (;;) {
Reference r;
synchronized (lock) {
if (pending != null) {
r = pending;
Reference rn = r.next;
// 从pending中取下一个元素,如果后继为空,则next指向自身 pending = (rn == r) ? null : rn;
r.next = r;
} else {
try {
// 没有则等待,后续加入元素会调用lock.notify唤醒
lock.wait();
} catch (InterruptedException x) { }
continue;
}
}
// ...
ReferenceQueue q = r.queue;
// 如果该Reference注册了对应的Queue,则加入到该Queue中
if (q != ReferenceQueue.NULL) q.enqueue(r);
}
}
}
// 用于标识没有注册Queue
static ReferenceQueue NULL = new Null();
// 用于标识已经处于对应的Queue中
static ReferenceQueue ENQUEUED = new Null();
static private class Lock { };
/* 互斥锁,用于同步ReferenceHandler的enqueue和用户线程操作的remove和poll出队操作 */
private Lock lock = new Lock();
// 队列
private volatile Reference<? extends T> head = null;
// 队列中的元素个数
private long queueLength = 0;
boolean enqueue(Reference<? extends T> r) {
synchronized (r) {
// 判断是否已经入队了
if (r.queue == ENQUEUED) return false;
synchronized (lock) {
r.queue = ENQUEUED;
// 单向循环
r.next = (head == null) ? r : head;
head = r;
queueLength++;
if (r instanceof FinalReference) {
sun.misc.VM.addFinalRefCount(1);
}
// 通知当前挂起的线程(调用remove时有可能会挂起)
lock.notifyAll();
return true;
}
}
}
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;
for (;;) {
// 否则等待,由enqueue时notify唤醒
lock.wait(timeout);
r = reallyPoll();
if (r != null) return r;
if (timeout != 0) return null;
}
}
}
// 创建一个引用队列 ReferenceQueue queue = new ReferenceQueue(); // 创建虚引用,此时状态为Active,并且Reference.pending为空,当前Reference.queue = 上面创建的queue,并且next=null WeakReference reference = new WeakReference(new Object(), queue); System.out.println(reference); // 当GC执行后,由于是虚引用,所以回收该object对象,并且置于pending上,此时reference的状态为PENDING System.gc(); /* ReferenceHandler从pending中取下该元素,并且将该元素放入到queue中,此时Reference状态为ENQUEUED,Reference.queue = ReferenceENQUEUED */ /* 当从queue里面取出该元素,则变为INACTIVE,Reference.queue = Reference.NULL */ Reference reference1 = queue.remove(); System.out.println(reference1);
// 外部WeakHashMap属性
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
/* 这里采用了集成WeakReference而不是直接使用,是因为当被回收的时候,具体的Key是不知道的,这里需要往WeakReference额外加入一些属性,以便在被回收后通知时,能够定位到具体的Key/value */
private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
// 这里属性不能加入key,否则会导致存在强引用而不能被视为WeakReference回收掉
V value;
int hash;
Entry<K,V> next;
Entry(Object key, V value,
ReferenceQueue<Object> queue,
int hash, Entry<K,V> next) {
super(key, queue);
this.value = value;
this.hash = hash;
this.next = next;
}
// ...
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有