0

I have a third party Java library that provides a resource.

TheResource resource = TheResource.create()

Sometime later, when I'm done with the resource, I'm supposed to close the resource

resource.close()

According to the library documentation, the resource I create is a ThreadLocal variable. That means the resource is created per thread, and it sticks to the thread. My question is, is it possible to call the close() method automatically when the associated thread is finished? I think I can do it if the thread is my own custom thread because I can engage with the lifecycle of the thread. But my question is about those threads provided by the system.

For instance, in Android's SyncAdapter provides a thread for you. And I don't know how the thread is finished. I'm wondering if there's some kind of 'hook' mechanism in terms of threads' lifecycle so that I can close ThreadLocal resources of the threads.

Jake
  • 1,518
  • 2
  • 14
  • 20
  • 1
    I don't follow you. You say the library creates a resource, but then the library docs say that _you_ must provide a `ThreadLocal`? Maybe if you provided some code example or some direct quotes from the documentation... – Solomon Slow Feb 04 '16 at 19:58
  • I think understand what you are trying to do but also a pretty much difficult if not impossible without some weird java black magic. Even if you were able to listen for thread to finish you would have to call `ThreadLocal.remove()` in that dead thread context. Maybe `Object.finalize()` is the closest you can get but then it requires subclassing that context thread. – Whome Feb 04 '16 at 22:06

2 Answers2

0

The resource is likely not created statically but ThreadLocal so several threads may use their own resource independently.

Therefore your thread that calls TheResource.create() is that thread. It is your responsibility for a second and third call to create to do this on the same thread. And then close at that thread's end - on the same thread.

(Probably closing does not need to be done on the same thread.)

You could pack that in a class.


Fpr instance:

public class ResourceManager {

    private static final Set<TheResource> resources = new HashSet<>();

    public static TheResource create() {
        TheResource res = TheResource.create();
        // Not needced: Thread thread = Tread.currentThread();
        resources.add(res);
        return res;
    }

    public static void shutdown() {
        resources.forEach(TheResource::close);
    }
}

And in an application shut down:

Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() { ResourceManager.shutDown(); }
});
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • I'm not sure I understand your answer correctly. Let me put my question this way: Is there a way to clean up ThreadLocal variables in a custom way when a thread is finished given that the thread is provided by the system for you. – Jake Feb 04 '16 at 21:35
  • That's sample code for "how to create a memory leak in three easy steps". Cleaning up the resources only at the end independent of their actual lifetime is generally bad behaviour. – Voo Feb 06 '16 at 07:13
  • @Voo it indeed would be ideal to immediately clean up after usage. Not doing that can be for reasons of caching and so on, so the question seems a solid use-case; especially as _asking_ about the leackage.. – Joop Eggen Feb 06 '16 at 15:07
0

There does not seem to be any available callback in the ThreadLocal mechanism. This leaves garbage collection, since all the objects in a dead thread's ThreadLocalMap will eventually get garbage collected. So you could override Object.finalize() to do your cleanup. Not ideal but...

Rich MacDonald
  • 895
  • 6
  • 5