/** * 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<>();