今天闲来无事,自己写了段代码试了一下几种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不需要这样。