1 引用队列的监控和回调
当创建一个引用队列时,我们需要对这个队列进行监控,即开启一个新的线程来循环判断此队列信息,并从中获取相应的数据信息。在guava中,也是通过创建一个线程然后在循环中进行判断,如下所示(类com.google.common.base.internal.Finalizer):
Thread thread = new Thread(finalizer); thread.setName(Finalizer.class.getName()); thread.setDaemon(true); thread.start();
即创建一个以finalizer runnable对象的线程,然后启动之,为避免阻止进程结束,采用了后台线程的模式。那在这个finalizer中,其运行如下所示:
while (true) { try { if (!cleanUp(queue.remove())) { break; } } catch (InterruptedException e) { /* ignore */ } }
即不断地获取队列中的数据,然后调用cleanUp方法.而在cleanUp方法中,其实就是调用相应对象的回调方法,即当一个对象已经被gc时的回调。
在guava中,从队列中移除的是一个是reference对象。在java体系中,并没有在reference对象中定义相应的回调方法,因此guava为jdk的reference增加了新的定义接口,称之为FinalizableReference。在这个接口中,即定义了一个相应的回调函数,如下所示:
/** 当引用被gc之后,此方法会被触发调用 */ void finalizeReferent();
因为增加了新的接口,因此我们自己来使用的话,就即要继承于jdk的weakReference,又要实现此接口。为方便,guava定义了3套与jdk兼容的引用对象。即FinalizableWeakReference,FinalizableSoftReference和FinalizablePhantomReference。可以理解为就是一个对jdk原类型的一个适配。