演示代码:
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
Object test = new Object();
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
PhantomReference<Object> p = new PhantomReference<Object>(test, q);
Object lock = new Object();
while (true) {
synchronized (lock) {
//q.poll() is null always,why?
if (q.poll() != null) {
break;
}
//System.gc();
lock.wait();
}
}
System.out.println(1111111);
}
}
我测试了代码,但它总是死循环。代码 (System.out.println(1111111);) 无法执行,q.poll() reurn null。
我认为如果测试对象被 GC 删除,q.poll() 将返回 p 对象,然后中断循环,但调用此演示代码,这与我的想法不同
编辑:我修改了演示代码,它现在可以工作了。
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
Object test = new Object();
ReferenceQueue<Object> q = new ReferenceQueue<Object>();
PhantomReference<Object> p = new PhantomReference<Object>(test, q);
Object lock = new Object();
while (true) {
synchronized (lock) {
if (q.poll() != null) {
break;
}
test = null; //it is important
System.gc();
lock.wait(100);//should not lock.wait()
}
}
System.out.println(1111111);
}
}
正如某人所说,语句(test = null)是key.GC收集分配null的测试对象。