using ThreadLocal to cache data in request scope

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了using ThreadLocal to cache data in request scope相关的知识,希望对你有一定的参考价值。

/** * 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的主要内容,如果未能解决你的问题,请参考以下文章

VS2010链接Mysql Authentication to host 'xx' for user 'root' using method 'caching_

Cache 命中率

cache java

How to use JDBC-Authentication of Spring Boot/Spring Security with Flyway

Linux手动释放内存

Unable to lock the administration directory (/var/lib/dpkg/),is another process using it?