今天闲来无事,自己写了段代码试了一下几种Reference,但是在PhantomReference的时候,遇到了一点问题。还望指点迷津。
问题是这样的。
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import org.junit.Test;
public class PhantomReferenceTest {
@Test
public void testReference() {
Object object = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
Reference<Object> reference = new PhantomReference<Object>(object,
referenceQueue);
System.out.println(reference);
System.out.println(reference.isEnqueued());
object = null;
System.gc();
System.out.println(reference.isEnqueued());
try {
System.out.println(referenceQueue.remove(2000));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行以后得到以下结果:
java.lang.ref.PhantomReference@cac268
false
true
java.lang.ref.PhantomReference@cac268
这说明,我的reference对象被加入到了ReferenceQueue中。但是,现在我重新写了个类,在他的finalize方法中加了一句话。
public class TestObject {
@Override
protected void finalize() throws Throwable {
System.out.println("finalize method executed");
super.finalize();
}
}
然后再运行junit
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import org.junit.Test;
public class PhantomReferenceTest {
@Test
public void testReference() {
Object object = new TestObject(); // 换成TestObject
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
Reference<Object> reference = new PhantomReference<Object>(object,
referenceQueue);
System.out.println(reference);
System.out.println(reference.isEnqueued());
object = null;
System.gc();
System.out.println(reference.isEnqueued());
try {
System.out.println(referenceQueue.remove(2000));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果为:
java.lang.ref.PhantomReference@1cde100
false
false
finalize method executed
null
这说明我的reference对象没有被加到ReferenceQueue中,对此,我不解,为什么重写了finalize方法以后,就不能加进去,还望各位指点。
问题补充
自己顶起来,高人们啊,都别潜水了。出来活动活动。
问题补充
IcyFenix 写道
把“System.gc();”换成“System.gc();Thread.sleep(100);System.gc();”试试
等一等Finalizer线程把F-Quence扫干净。
等一等Finalizer线程把F-Quence扫干净。
啊,果然,为什么要多写一次System.gc();呢?而其他的SoftReference,WeakReference不需要这样。