Reference提供了一些引用的基本方法以及静态代码块最高优先级启动ReferenceHandler线程
package xxx;
/**
* Abstract base class for reference objects. This class defines the
* operations common to all reference objects. Because reference objects are
* implemented in close cooperation with the garbage collector, this class may
* not be subclassed directly.
* 引用对象的抽象基类。这个类定义了所有引用对象的通用行为。
* 因为引用对象是通过与垃圾回收期密切合作来实现的,所以不能直接为此类创建子类.
*
*
* @version 1.43, 04/10/06
* @author Mark Reinhold
* @since 1.2
*/
public abstract class Reference<T> {
/* A Reference instance is in one of four possible internal states:
* 一种引用实例是可能是四种内部状态之一:
* Active: Subject to special treatment by the garbage collector. Some
* time after the collector detects that the reachability of the
* referent has changed to the appropriate state, it changes the
* instance's state to either Pending or Inactive, depending upon
* whether or not the instance was registered with a queue when it was
* created. In the former case it also adds the instance to the
* pending-Reference list. Newly-created instances are Active.
* 激活:垃圾回收器特别处理的主题。有时候在回收器检测到被引用(对象)的可达性被改变成适当
* 的状态,它会把实例的状态改变成等待状态或者未激活状态,这取决于实例是否被一个队列注册当
* 它被创建。在前一种情况下(等待状态),它也往等待-引用集合增加实例。
*
*
* Pending: An element of the pending-Reference list, waiting to be
* enqueued by the Reference-handler thread. Unregistered instances
* are never in this state.
* 等待:一个等待-引用集合里的元素,等待被引用处理线程放入队列中。
* 未注册的实例永远不会在这个状态
*
* Enqueued: An element of the queue with which the instance was
* registered when it was created. When an instance is removed from
* its ReferenceQueue, it is made Inactive. Unregistered instances are
* never in this state.
* 入队:实例被创建的时候被登记注册成一个队列的元素。当一个实例从引用队列中删除,它变成非激活状态。
* 未注册的实例永远不会在这个状态。
*
* Inactive: Nothing more to do. Once an instance becomes Inactive its
* state will never change again.
* 非激活:不会再做什么。一旦一个实例成为非激活的,它的状态永远不会被改变。
*
*
* The state is encoded in the queue and next fields as follows:
* 状态在队列里被处理并且每个状态所表现的属性如下:
*
*
* Active: queue = ReferenceQueue with which instance is registered, or
* ReferenceQueue.NULL if it was not registered with a queue; next =
* null.
* 激活:queue=引用队列时候,实例被它注册,
* 或者实例不被注册,当queue=ReferenceQueue.NULL时候;
* next=null.
*
* Pending: queue = ReferenceQueue with which instance is registered;
* next = Following instance in queue, or this if at end of list.
* 等待:queue=引用队列时候,实例被它注册,
* next=剩下的queue队列里面的实例,或者=this,如果this是队列的最后一个。
*
* Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
* in queue, or this if at end of list.
* 入队:queue=ReferenceQueue.ENQUEUED
* next=剩下的queue队列里面的实例,或者=this,如果this是队列的最后一个
*
*
* Inactive: queue = ReferenceQueue.NULL; next = this.
* 终止:队列=ReferenceQueue.NULL next=this
*
* With this scheme the collector need only examine the next field in order
* to determine whether a Reference instance requires special treatment: If
* the next field is null then the instance is active; if it is non-null,
* then the collector should treat the instance normally.
*
*
*
* To ensure that concurrent collector can discover active Reference
* objects without interfering with application threads that may apply
* the enqueue() method to those objects, collectors should link
* discovered objects through the discovered field.
*/
private T referent; /* Treated specially by GC */ //被GC引用的对象
ReferenceQueue<? super T> queue;//引用队列
Reference next;//下个引用
transient private Reference<T> discovered; /* used by VM *///被VM引用的瞬态对象
/* Object used to synchronize with the garbage collector. The collector
* must acquire this lock at the beginning of each collection cycle. It is
* therefore critical that any code holding this lock complete as quickly
* as possible, allocate no new objects, and avoid calling user code.
* GC线程在回收的时候的锁
* 对象被用来和GC同步。GC必须获得锁在每个回收的生命周期。
* 更关键的是任何持有锁的代码尽可能快的执行完,没有分配新的对象,并避免使用使用者的代码。
*
*/
static private class Lock { };
private static Lock lock = new Lock();
/* List of References waiting to be enqueued. The collector adds
* References to this list, while the Reference-handler thread removes
* them. This list is protected by the above lock object.
* 排队的引用集合。当处理引用的线程删除引用时候,收集器添加引用到这个集合。
* 这个集合受上面的对象锁保护。
*/
private static Reference pending = null;
/* High-priority thread to enqueue pending References
* 处理排队等待的引用的高优先的线程
*/
private static class ReferenceHandler extends Thread {
ReferenceHandler(ThreadGroup g, String name) {
super(g, name);
}
public void run() {
for (;;) {
/*
* 给pending赋值
* 如果pending.next=pending,pending=null;否则pending=pengding.next,最后把pending.next=pending
* 下次执行线程里的代码时候pending=null了,再下次执行同步代码块就线程阻塞了
*
* 如果pending属性为空,释放锁的对象监视器,阻塞当前线程
* */
Reference r;
synchronized (lock) {
if (pending != null) {
r = pending;
Reference rn = r.next;
pending = (rn == r) ? null : rn;
r.next = r;
} else {
try {
lock.wait();
} catch (InterruptedException x) { }
continue;
}
}
// Fast path for cleaners
if (r instanceof Cleaner) {
((Cleaner)r).clean();
continue;
}
/*
* ReferenceQueue.NULL的实现:
* private static class Null extends ReferenceQueue {
* boolean enqueue(Reference r) {
* return false;
}
}
* 如果Q不为空,把引用放入Queue
* 在刚创建一个引用,第二个参数没放Queue时候,为空。
* */
ReferenceQueue q = r.queue;
if (q != ReferenceQueue.NULL) q.enqueue(r);
}
}
}
static {
//取得当前线程组
ThreadGroup tg = Thread.currentThread().getThreadGroup();
//取得最上层的System线程组
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());
//创建线程对象
Thread handler = new ReferenceHandler(tg, "Reference Handler");
/* If there were a special system-only priority greater than
* MAX_PRIORITY, it would be used here
*/
handler.setPriority(Thread.MAX_PRIORITY);//设置最高优先级
handler.setDaemon(true);//标记守护线程或用户线程
handler.start();//守护线程启动
}
/* -- Referent accessor and setters -- */
/**
* Returns this reference object's referent. If this reference object has
* been cleared, either by the program or by the garbage collector, then
* this method returns <code>null</code>.
*
* @return The object to which this reference refers, or
* <code>null</code> if this reference object has been cleared
* 获得引用对象
*/
public T get() {
return this.referent;
}
/**
* Clears this reference object. Invoking this method will not cause this
* object to be enqueued.
*
* <p> This method is invoked only by Java code; when the garbage collector
* clears references it does so directly, without invoking this method.
* 清除引用对象
*/
public void clear() {
this.referent = null;
}
/* -- Queue operations -- */
/**
* Tells whether or not this reference object has been enqueued, either by
* the program or by the garbage collector. If this reference object was
* not registered with a queue when it was created, then this method will
* always return <code>false</code>.
*
* @return <code>true</code> if and only if this reference object has
* been enqueued
*/
public boolean isEnqueued() {
/* In terms of the internal states, this predicate actually tests
whether the instance is either Pending or Enqueued
是否处于等待状态
判断条件:队列不为空,
它的next属性不为空。
刚初始化一个Reference时候,next属性肯定是空的,因此肯定不处于等待状态
*/
synchronized (this) {
return (this.queue != ReferenceQueue.NULL) && (this.next != null);
}
}
/**
* Adds this reference object to the queue with which it is registered,
* if any.
*
* <p> This method is invoked only by Java code; when the garbage collector
* enqueues references it does so directly, without invoking this method.
*
* @return <code>true</code> if this reference object was successfully
* enqueued; <code>false</code> if it was already enqueued or if
* it was not registered with a queue when it was created
* 加入等待队列
*/
public boolean enqueue() {
return this.queue.enqueue(this);
}
/* -- Constructors -- */
Reference(T referent) {
this(referent, null);
}
Reference(T referent, ReferenceQueue<? super T> queue) {
this.referent = referent;
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
}
}