虚引用(Phantom Reference)是Java中一种比较特殊的引用类型,和软引用、弱引用类似,虚引用不会影响垃圾回收对象的生命周期,但是虚引用主要是用于对象被回收时的通知。
虚引用主要有两个作用:
- 控制对象回收时机
虚引用被实例化时需要与一个引用队列相关联,当对象被垃圾回收器标记为回收时,虚引用会被放入引用队列中,这时我们就可以通过判断引用队列中是否有虚引用对象来判断被引用的对象是否已经被回收。
下面是一个示例代码:
Object obj = new Object();
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> ref = new PhantomReference<>(obj, queue);
obj = null;
System.gc();
try {
Reference<?> reference = queue.remove();
if (reference instanceof PhantomReference) {
System.out.println("Object has been detected as garbage collected.");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
在上述示例中,我们创建了一个虚引用对象ref
并与一个引用队列queue
相关联。接着我们将对象obj
的引用设置为null,并调用System.gc()
触发一次垃圾回收。最后我们使用queue.remove()
方法检查引用队列是否有被回收的对象,如果queue.remove()
方法返回的对象是虚引用对象,那么说明被虚引用所引用的对象已经被成功回收了。
- 执行某些资源释放动作
在对象被回收时,虚引用可以用来执行一些必要的资源释放动作。这在一些需要进行资源清理的场合下比较常用。
下面是一个虚引用执行资源释放动作的示例代码:
public class ResourceCleaner {
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private final List<PhantomReference<?>> cleanup = new ArrayList<>();
public <T extends AutoCloseable> void track(T resource, Runnable cleanupAction) {
cleanup.add(new PhantomReference<>(resource, queue));
new Thread(() -> {
try {
queue.remove().clear();
} catch (InterruptedException e) {
// ignore
}
cleanupAction.run();
}).start();
}
}
在上述代码中,我们定义了一个ResourceCleaner
类用于跟踪需要释放资源的对象。track()
方法接收需要释放资源的对象和资源释放动作,然后将虚引用对象添加到列表中。同时,我们创建了一个线程用于监控引用队列,一旦被虚引用所引用的对象被标记回收,就会通过线程启动资源释放动作。
参考资料:
- https://blog.csdn.net/yasinshaw/article/details/88871589
- https://www.baeldung.com/java-phantom-reference
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:虚引用的作用是什么? - Python技术站