关于PhantomReference的问题求解

今天闲来无事,自己写了段代码试了一下几种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扫干净。


啊,果然,为什么要多写一次System.gc();呢?而其他的SoftReference,WeakReference不需要这样。

1个回答

把“System.gc();”换成“System.gc();Thread.sleep(100);System.gc();”试试
等一等Finalizer线程把F-Quence扫干净。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!