using ThreadLocal to cache data in request scope
阿新 • • 發佈:2018-04-18
thread stack;reques
/**
* aim to cache the data that‘s accessed frequently and costly.
* @param <K>
* @param <V>
*/
public interface Cache<K,V> {
V get(K k);
void put(K k, V v);
void clean();
int size();
}
/** *this class is an implementor from Cache.and It cache data in thread local. * @see Cache * @see ThreadLocal */ public class ThreadLocalCache<K,V> implements Cache<K,V>{ private ThreadLocal<Map<K,V>> threadLocal = new ThreadLocal<>(); public ThreadLocal<Map<K, V>> getThreadLocal() { return threadLocal; } public void setThreadLocal(ThreadLocal<Map<K, V>> threadLocal) { this.threadLocal = threadLocal; } private Map<K, V> getThreadLocalMap(){ Map<K, V> map = getThreadLocal().get(); if (map == null){ map = new HashMap(); getThreadLocal().set(map); } return map; } protected void cleanThreadLocal(){ Map<K, V> map = getThreadLocal().get(); if (map != null) map.clear(); getThreadLocal().remove(); } private int sizeThreadLocal(){ Map<K, V> map = threadLocal.get(); return map == null ? 0 : map.size(); } @Override public V get(K k) { return getThreadLocalMap().get(k); } @Override public void put(K k, V v) { getThreadLocalMap().put(k,v); } @Override public void clean() { cleanThreadLocal(); } @Override public int size() { return sizeThreadLocal(); } }
/** * this class is to create a threadLocal through Factory. * @see ThreadLocalFactory * @see com.pretang.cloud.service.agent.AgentRpcService */ public class FactoryThreadLocalCache<K,V> extends ThreadLocalCache<K,V> { public FactoryThreadLocalCache() { super(); super.setThreadLocal(ThreadLocalFactory.getThreadLocal()); } }
/** * this class is a building ThreadLocal factory. And to manage the lifetime of the threadLocal. * @see FactoryThreadLocalCache */ public abstract class ThreadLocalFactory { // a sharing ThreadLocal in heap. private static final ThreadLocal threadLocal = new ThreadLocal(); /** * get a threadLocal instance. * @return */ public static ThreadLocal getThreadLocal(){ return threadLocal; } /** * clean the threadLocal */ public static void cleanThreadLocal(){ Object obj = threadLocal.get(); if (null != obj && obj instanceof Collection) ((Collection) obj).clear(); threadLocal.remove(); } }
@Component
@WebFilter
public class CustomerFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
// clean the variables in threads for a request
ThreadLocalFactory.cleanThreadLocal();
}
@Override
public void destroy() {
}
}
private static final Cache<Integer, AgentDto> agentDtoCache = new FactoryThreadLocalCache<>();
private static final Cache<Integer, AgentUser> agentUserCache = new FactoryThreadLocalCache<>();
using ThreadLocal to cache data in request scope