iteye_11085 2011-08-01 13:42
浏览 309
已采纳

关于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条回答

  • seicefire 2011-08-01 13:42
    关注

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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料