Using ReferenceQueue and WeakReference

java

Solution

First, if it is only about closing, use `PhantomReference`. Next, from the reference queue, `poll()` does not guarantee that you will get the reference back. and you will never get the actual object (referent) back.

If you want to make sure your `Closeable`s are closed you have to keep track of them yourself lets say in a `Map<Reference<?>, Closeable>`. Then when you `poll()` your reference queue, you will eventually get the `ref` then you have to use it to get the `Closeable` from the map.

   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();
   }

Note If you don't have a real reason to do this or if you do not understand what are you really doing, DO NOT do this kind of thing.

You can close your files in `finally` and BTW if it is about files, sockets, etc, they are closed for you (they already implement `finalize()`

Problem

I want to properly close Closeable object when it's no longer referenced by other threads. I wrote some small test, but after object is enqueued the get method return null, i.e. the poll method returns proper Object which has no referent. ``` 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(); } ``` Thanks in advance. Any help will be appreciated.

Original source