定义
ReferenceQueue是引用队列,用于存放待回收的引用对象。
说明
对于软引用、弱引用和虚引用,如果我们希望当一个对象被垃圾回收器回收时能得到通知,进行额外的处理,这时候就需要使用到引用队列了。
在一个对象被垃圾回收器扫描到将要进行回收时,其相应的引用包装类,即reference对象会被放入其注册的引用队列queue中。可以从queue中获取到相应的对象信息,同时进行额外的处理。比如反向操作,数据清理,资源释放等。
使用例子
public class ReferenceQueueTest { private static ReferenceQueue<byte[]> rq = new ReferenceQueue<>(); private static int _1M = 1024 * 1024; public static void main(String[] args) { Object value = new Object(); Map<WeakReference<byte[]>, Object> map = new HashMap<>(); Thread thread = new Thread(ReferenceQueueTest::run); thread.setDaemon(true); thread.start(); for(int i = 0;i < 100;i++) { byte[] bytes = new byte[_1M]; WeakReference<byte[]> weakReference = new WeakReference<>(bytes, rq); map.put(weakReference, value); } System.out.println("map.size->" + map.size()); int aliveNum = 0; for (Map.Entry<WeakReference<byte[]>, Object> entry : map.entrySet()){ if (entry != null){ if (entry.getKey().get() != null){ aliveNum++; } } } System.out.println("100个对象中存活的对象数量:" + aliveNum); } private static void run() { try { int n = 0; WeakReference k; while ((k = (WeakReference) rq.remove()) != null) { System.out.println((++n) + "回收了:" + k); } } catch (InterruptedException e) { e.printStackTrace(); } } }这里有一个小栗子,main方法中,创建了一条线程,使用死循环来从引用队列中获取元素,监控对象被回收的状态。然后循环往map中添加了100个映射关系,以下是运行结果:
...前面省略了大量相似输出 85回收了:java.lang.ref.WeakReference@7106e68e 86回收了:java.lang.ref.WeakReference@1f17ae12 87回收了:java.lang.ref.WeakReference@c4437c4 map.size->100 100个对象中存活的对象数量:12通过配合使用ReferenceQueue,可以较好的监控对象的生存状态。
成员变量
ReferenceQueue中内部成员变量也很少,主要有这么几个:
static ReferenceQueue<Object> NULL = new Null<>(); static ReferenceQueue<Object> ENQUEUED = new Null<>();有两个用来做为特殊标记的静态成员变量,一个是NULL,一个是ENQUEUE,上一篇中说的ReferenceQueue.NULL和ReferenceQueue.ENQUEUED就是这两个家伙。
来看看Null长什么样:
private static
