搜索

首页  >  问答  >  正文

java - 关于虚引用PhantomReference

在<<深入理解Java虚拟机>>3.2.3中有这么一句话

“为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。”

请问利用虚引用在对象被回收时收到一个系统通知要怎么实现呢?能提供下示例代码吗?

迷茫迷茫2769 天前387

全部回复(1)我来回复

  • 巴扎黑

    巴扎黑2017-04-17 17:14:09

    在这里看到了PhantomReference的用法:

    import java.lang.ref.PhantomReference;
    import java.lang.ref.Reference;
    import java.lang.ref.ReferenceQueue;
    import java.lang.reflect.Field;
    
    public class Test {
        public static boolean isRun = true;
    
        @SuppressWarnings("static-access")
        public static void main(String[] args) throws Exception {
            String abc = new String("abc");
            System.out.println(abc.getClass() + "@" + abc.hashCode());
            final ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();
            new Thread() {
                public void run() {
                    while (isRun) {
                        Object obj = referenceQueue.poll();
                        if (obj != null) {
                            try {
                                Field rereferent = Reference.class
                                        .getDeclaredField("referent");
                                rereferent.setAccessible(true);
                                Object result = rereferent.get(obj);
                                System.out.println("gc will collect:"
                                        + result.getClass() + "@"
                                        + result.hashCode() + "\t"
                                        + (String) result);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }.start();
            PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc,
                    referenceQueue);
            abc = null;
            Thread.currentThread().sleep(3000);
            System.gc();
            Thread.currentThread().sleep(3000);
            isRun = false;
        }
    }

    原来要和ReferenceQueue搭配使用。

    回复
    0
  • 取消回复