我有一个singleton类,因此
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;
}
}
在构造函数完成之前,我将singleton实例泄漏到监视器线程,有什么更好的方法?
让缓存变得易失性会解决这个问题吗?
正如user2677485所提到的,您应该使用ThreadLocal并实现initialValue方法。另一点是,Handler实现应该实现finalize方法,这样当GC回收该方法时,就会调用该方法,并且您可以清理资源。
代码可以简化为以下内容:
public class HandlerCache {
private static final handlers = new ThreadLocal<Handler>() {
protected Handler initializeValue() {
return HandlerFactory.get(...);
}
};
public static Handler getHandler() {
return handlers.get();
}
}
您可以使用静态函数初始化实例,该函数将首先构造HandlerCache,然后启动线程,而不是在HandlerCache构造函数中启动线程。