小编典典

使用ReferenceQueue和WeakReference

java

我想在其他线程不再引用它时正确关闭Closeable对象。

我写了一些小测试,但是将对象加入队列后,get方法返回null,即poll方法返回没有引用的正确Object。

  public static void main(String[] args)
  {
   ReferenceQueue<Closeable> reaped = new ReferenceQueue<Closeable>();
   Closeable s = <SOME CLOSEABLE IMPL>;
   WeakReference<Closeable> ws = new WeakReference<Closeable>(s, reaped);
   s = null;

   System.gc();
   Closeable ro = (Closeable)reaped.poll().get();
   ro.close();
  }

提前致谢。任何帮助将不胜感激。


阅读 284

收藏
2020-11-16

共1个答案

小编典典

首先,如果仅是关闭,请使用PhantomReference。接下来,从参考队列中,poll()不保证您将获得参考。并且您将永远不会找回实际的对象(参考对象)。

如果要确保Closeable已关闭,则必须自己跟踪它们Map<Reference<?>, Closeable>。然后,当poll()您使用参考队列时,最终将获得,ref然后必须使用它来Closeable从地图获取。

   class MyThing {
      Closeable c;
   }

   Map<Reference<MyThing>, Closeable> m = new HashMap();
   ReferenceQueue<MyThing> reaped = new ReferenceQueue<MyThing>();

   MyThing mt = new MyThing();
   mt.c = new MyClosable();

   Reference<MyThing> pref = new PhantomReference<MyThing>(mt, reaped);
   m.put(pref, mt.c);

   mt = null;


   System.gc();
   Reference<MyThing> rf = reaped.poll();
   while (rf != null) {
     m.get(rf).close(); 
     rf = reaped.poll();
   }

注意 如果您没有真正的理由执行此操作,或者您不了解自己的实际操作,请不要执行此类操作。

您可以关闭您的文件中finally,并顺便说一句,如果它是关于文件,插座等,他们关闭了你(他们已经实现了finalize()

2020-11-16