user2677485
user2677485

Reputation: 107

java concurrency - singleton design with a monitor thread

I have a singleton class thus

public final class HandlerCache {
    //the cache maintains a handler per thread 
    private final Map<Thread, Handler> cache = new ConcurrentHashMap<>();

    private final Thread monitor;

    private static final HandlerCache INSTANCE = new HandlerCache();

    private HandlerCache() {
        monitor = new Thread() {
        //periodically monitor cache and close handlers when a thread has died
        }
        monitor.start()
    }

    public static HandlerCache getInstance() {
        return INSTANCE;
    }

    public Handler getHandler() throws Exception {
        final Thread thread = Thread.currentThread();
        Handler handler = cache.get(thread);

        if (!(handler == null))
            return handler;

        handler = HandlerFactory.get(getHandlerFromName(thread.getName()));
        cache.put(thread, handler);
        return handler;
    }

}

I am leaking the singleton instance to the monitor thread before the constructor is finished, what is the better way ?

Will making cache volatile will fix the issue ?

Upvotes: 0

Views: 353

Answers (2)

Claudio Corsi
Claudio Corsi

Reputation: 359

As mentioned by user2677485, you should be using a ThreadLocal and implement the initialValue method. The other point is that the Handler implementation should implement the finalize method so that when it is being reclaimed by the GC this method will be called and you can clean up your resources.

The code can be simplified as something like the following:

public class HandlerCache {

   private static final handlers = new ThreadLocal<Handler>() {
        protected Handler initializeValue() {
              return HandlerFactory.get(...);
        }
   };

   public static Handler getHandler() {
        return handlers.get();
   }

}

Upvotes: 1

Warren Dew
Warren Dew

Reputation: 8928

Rather than starting the thread within the HandlerCache constructor, you could initialize the instance using a static function that would first construct the HandlerCache and then start the thread.

Upvotes: 0

Related Questions