使用ReferenceQueue和WeakReference

yan*_*yan 10 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();
  }
Run Code Online (Sandbox Code Playgroud)

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

Op *_*kel 7

首先,如果它只是关闭,请使用PhantomReference.接下来,从引用队列中,poll()不保证您将获得引用.而且你永远不会得到实际的物体(指示物).

如果你想确保你的Closeables关闭,你必须自己跟踪它们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();
   }
Run Code Online (Sandbox Code Playgroud)

注意如果您没有真正的理由这样做或者您不理解您在做什么,请不要这样做.

您可以关闭文件finally和BTW,如果它是关于文件,套接字等,它们是关闭的(他们已经实现finalize()